メモリをイメージする事

少し、メモリの使われ方について考えさせられる出来事がありました。

例えば、以下のソースを見て、即座に気持ち悪さを感じられるかどうかは、一つのステータスかもしれません。

public class Foo {
	public String getLine(int i){
		return "Line - " + i;
	}
}
public class Main {
	public static void main(String[] args){
		for(int i = 0;i<100;i++){
			Foo myFoo = new Foo();
			System.out.println(myFoo.getLine(i));
		}
	}
}

もちろん、Mainクラスは次のように書いたほうが良いでしょう。

public class Main {
	public static void main(String[] args){
		Foo myFoo = new Foo();
		for(int i = 0;i<100;i++){
			System.out.println(myFoo.getLine(i));
		}
	}
}

では、次のコードを見て、メモリの動きをイメージできるでしょうか?

public class Foo {
	public static String getLine(int i){
		return "Line - " + i;
	}
}
public class Main {
	public static void main(String[] args){
		for(int i = 0;i<100;i++)
			System.out.println(Foo.getLine(i));
	}
}

こんな場合はどうでしょうか?

public class Foo {
	public static final Foo Instance = new Foo();
	public String getLine(int i){
		return "Line - " + i;
	}
}
public class Main {
	public static void main(String[] args){
		for(int i = 0;i<100;i++)
			System.out.println(Foo.Instance.getLine(i));
	}
}

JavaC#は明示的にメモリ管理を行わない言語です。
難しいことを考えずに使い捨てでオブジェクトを量産できるのも、これらの言語の魅力ではありますが・・・
パフォーマンスを意識してプログラミングする場合、ボトルネックを見つけ出すには、メモリ上で何が行われているかを知っていたほうが有利です。

スタックに何が積まれて、どのタイミングでヒープにオブジェクトが作られ、どのように呼び出されるのか。そのオブジェクトが開放されてGC対象になるのはどこか。
こういった「イメージ」を思い浮かべる習慣を身につける事ができたのは、次の書籍のおかげだったりします。

C言語ポインタが理解できない理由

C言語ポインタが理解できない理由

そうです、C言語です。

それほど経験のある言語では無いのですが、かなり色々な面で、この言語を学んだ経験が活きていたりします。(低レベルな言語だからでしょうか)

何にせよ、自分のできる限りで高品質なプログラムを書くために、今後も続けていきたい習慣です。