- PR -

ちょっと突っ込んだ質問ですが

投稿者投稿内容
isseki
大ベテラン
会議室デビュー日: 2001/11/05
投稿数: 107
投稿日時: 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 ]
t-wata
大ベテラン
会議室デビュー日: 2002/07/12
投稿数: 209
お住まい・勤務地: 東京
投稿日時: 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バイトです。
TO-R
ベテラン
会議室デビュー日: 2002/07/11
投稿数: 93
投稿日時: 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 ]

スキルアップ/キャリアアップ(JOB@IT)