RSS

Java-Gnomeでメモリリーク

    付与されたタグ:
  • Java

GTK+で書いたプログラムをJavaに移植してみた。移植作業自体は順調に進んで、同じような動作をするところまでこぎつけた…と思ったら問題発生。メモリを食い潰していく。はぁ?Javaだぞ、なんでだと思った。どうも画面の書き直しあたりでおかしいところまではわかった。JNIを使っているから変なことになってんのかなと思ったりもしつつ…。

ここでメモリリークを調べるツールを導入だとEclipse TPTPを導入した。しかし、なぜか、モニターが起動しない。そこでごにょごにょ探すとlibstdc++5が必要だと。そんなのどこで調べたらわかるんだか。

なんとかTPTPをインストールしてメモリのプロファイルを取る。あれ?とてもリークしているように見えない。

ふとtopを見るとjavaではなくてXorgがメモリを使っていた? Xサーバーのメモリですか。どういう加減かいまいちわからない。最小再現コードがきちんとできたので置いておく。new Context(widget.getWindow())かw.setSizeRequest(640,400)のどちらかがなければメモリリークの現象は起こらない。どういう状況なのかいまいちわからない…。

ちなみにJava-Gnomeのバージョンは4.0.15。4.1でGTK+3に対応するように見えるので、そうなると描画周りが変更になるのであまり深く追求する気にもならない。

import java.util.Timer;
import java.util.TimerTask;

import org.freedesktop.cairo.Context;
import org.gnome.gdk.Event;
import org.gnome.gdk.EventExpose;
import org.gnome.gtk.Gtk;
import org.gnome.gtk.Widget;
import org.gnome.gtk.Window;

public class LeakMemGTK {
	public static void main(String[] args) {
		Gtk.init(args);
		class EventLoop extends TimerTask {
			final Window w;
			EventLoop(Window w) {
				this.w = w;
			}
			public void run() {
				w.queueDraw();
			}
		}
		final Window w = new Window();
		Timer timer = new Timer(true);
		w.connect(new Widget.ExposeEvent() {
			public boolean onExposeEvent(Widget widget, EventExpose event) {
				new Context(widget.getWindow());
				return false;
			}
		});
		w.connect(new Window.DeleteEvent() {
			public boolean onDeleteEvent(Widget arg0, Event arg1) {
				Gtk.mainQuit();
				return false;
			}
		});
		EventLoop task = new EventLoop(w);
		timer.scheduleAtFixedRate(task, 0, 10);

		w.setSizeRequest(640, 480);
		w.setResizable(false);
		w.showAll();
		Gtk.main();
	}
}