メモリ使いすぎ 2 〜謝罪〜

正直ね、GCがまじめに働いていないと思っていたよ。
だってね、メモリの管理をしなくてもいいってGCが言っているので、本当にしなかったら、どうみてもメモリリークしてます。
なんでね、もうD言語やめて、C++で書き直そうかと本気で考えたよ。
プログラムにおいて超重要な意味があるメモリ管理ができないなんて、使い物にならないもの。

・・・。
いや、ごめん、デジタルマーズさん。

僕がバグっていました。

@ 原因
FIFOキューのテンプレートクラスが一度キューに入ったアイテムへの参照を永久にはずさないから、使わなくなったアイテムをGCが回収できない。

具体的には、QueueクラスとQueueNodeクラスというのがあって、QueueNodeクラスはnext/prevでアイテムのリンクストを作っていて、その上でQueueクラスがアイテムのリンクリストのtop/bottomを参照しているのだけど、shift(pop_front)したときに、top/bottomの参照だけ変えていて、アイテムのリンクストは、ずーとprev/nextで繋がったままになっている。

で、このFIFO Queueは非常に重要なクラスで、以下の場所で使われている。

  • 通信時の受信バッファリング
  • タスクのメッセージキュー
  • 待ち行列(タスク間のメッセージ交換/イベント/セマフォ

ここから、起動してから受信した通信パケットを全部持っていて、それを展開してタスク間でやり取りしているデータも全部持っているということになり、そりゃー、実質GCはほんとんど動いてないわな・・・と。

@ まとめ
GCがメモリを管理する言語は、「メモリの開放」は意識しなくてもよいが、「メモリへの参照を解除」は意識しないといけない。

  • 追記

ちょっとはよくなったような気がするけど、時間がたつとやっぱダメでした。