- - PR -
ちょっと突っ込んだ質問ですが
«前のページへ
1|2|3
| 投稿者 | 投稿内容 |
|---|---|
|
投稿日時: 2002-12-24 15:25
Stringを生成する前後のメモリ量を調べたところ
減ったのは確かに減ったですね。 下の結果について皆さんどう思われます? 【結果】(何度やっても同じ数値でした) A: Before the first new String freeMemory B: Before the second new String freeMemory C: After the second new String freeMemory A = 1275376 B = 1274720 Δ= 656 C = 1273864 Δ= 856 (new String()が6個にした場合) A = 1275304 B = 1274648 Δ= 656 C = 1273552 Δ= 1096 (new String()が12個にした場合) A = 1275160 B = 1274504 Δ= 656 C = 1272928 Δ= 1576 (new String()が24個にした場合) A = 1274872 B = 1274216 Δ= 656 C = 1271680 Δ= 2536 (new String()が48個にした場合) 【テストコード】 Runtime r = Runtime.getRuntime(); System.out.println("Before the first new String freeMemory = " + r.freeMemory()); String st = new String(); System.out.println("Before the second new String freeMemory = " + r.freeMemory()); // System.out.println("Before new String totalMemory = " + r.totalMemory()); st = new String(); st = new String(); st = new String(); st = new String(); st = new String(); st = new String(); : : System.out.println("After the second new String freeMemory = " + r.freeMemory()); [ メッセージ編集済み 編集者: isseki 編集日時 2002-12-24 15:28 ] [ メッセージ編集済み 編集者: isseki 編集日時 2002-12-24 16:10 ] |
|
投稿日時: 2002-12-24 18:40
ソースを見れば分かりますが、java.lang.Stringは、3つのprivate intと、1つのchar[]をインスタンス変数として持ってます。なので、
class TestObject extends java.lang.Object{ private int a,b,c; private char[] d; public TestObject(){ d = new char[0]; } } のようなクラスをつくって、それと比べてみればよいでしょう。 public class Test{ public static void main(String[] args){ Runtime r = Runtime.getRuntime(); long first,second; new TestObject(); // Stringと公平にするために一度インスタンスを作っておく TestObject st; first = r.freeMemory(); st = new TestObject(); second = r.freeMemory(); System.out.println("diff between first and second " + (first - second)); } } 結果は私の環境では、1インスタンス40バイトです。 ちなみにTestObjectをStringに変えた場合も1インスタンス40バイトです。 |
|
投稿日時: 2002-12-24 19:53
うちでも実験してみました。
--- public class Test { public static void main(String[] arg) { int i; String st[] = new String[100]; long b,a,la; Runtime r = Runtime.getRuntime(); System.gc(); la = r.freeMemory(); for (i = 0; i < 100; i++ ) { System.gc(); b = r.freeMemory(); st[i] = new String(""); // ここでインスタンス生成 a = r.freeMemory(); System.gc(); System.out.println(i+"\t"+st[i]+"\t"+b+"\t"+a+"\t"+(la-b)+"\t"+(b-a)); System.out.flush(); la = a; } } --- ポイントは、いちいちガーベージコレクションを呼んで、 妙なタイミングで開放が起こって誤差が出ないように しているところです(^^) プログラムをループさせていますが、System.gc()を呼ばないと それなりに面白い結果が見れます(^^) 各パターンを個別に実験せず、 for () { } for () { } のように、直列で実験すると、前回使っていた領域を開放する 様子が見れるので、更に楽しめます。 直列にして走らせて見ると、開放すべき領域があっても、 「即開放」するとは限らないようですね。 インスタンス生成の部分をいろいろ変えて実験してみました。 (1) st[i] = null のとき b-a : 0 (2) st[i] = new String() のとき b-a : 40 (3) st[i] = "Test" のとき b-a : 0 (4) st[i] = new String("Test") のとき b-a : 24 (5) st[i] = new String("") のとき b-a : 24 (6) st[i] = new String("1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ") のとき b-a : 24 (7) st[i] = new String(""+i) のとき b-a : 40 新たな謎は出てきていますが、 (6)で24文字を超える文字列を引数にして生成しても 24バイトの減少しか起こらないとか、 (7)で1桁の文字列でも2桁の文字列でも 40バイト固定とか… とりあえず、もともとの問題の「コードの複製は起こるのか?」の 答えは、「No」ということですよね。 [ メッセージ編集済み 編集者: TO-R 編集日時 2002-12-24 19:58 ] |
«前のページへ
1|2|3
