- PR -

32bitと64bit版JVMの挙動の違いについて

1
投稿者投稿内容
みらー
会議室デビュー日: 2002/12/06
投稿数: 6
投稿日時: 2007-11-11 15:45
お世話になっております。

今とあるライブラリの挙動を確認しているのですが、そのライブラリが内部で
巨大なバイト配列を使用しています。そのためメモリの使用量がかなり多くなるので
32bit版OSでは限界があり、64bit版OS(WinServer2003)+64bit版JVMを使用しようと
しました。ところが32bit版OSでは64bit版OSよりOutOfMemoryが起きやすいという現象が
起きております。

ためしに、以下のように10000000個の配列を作成することを繰り返すプログラムを
作成してしてみました。

---

private void allocateArray()
{
int cnt=0;

try
{
while(true)
{
cnt++;
int numInt=10000000;
int[] add = new int[numInt];
for(int i=0;i<numInt;i++)
{
add[i]=i; //何か値をいれないとメモリの使用量が増えない
}
alInt.add(add); //クラス変数のArrayListに値を保持させ、メモリが解放されないようにする
dispMemoryUsage();
}
}
catch(Exception ex)
{
ex.printStackTrace();
}
catch(Throwable th)
{
th.printStackTrace();
}
finally
{
System.out.println(cnt + "回実行できました");
dispMemoryUsage();
}
}

private void dispMemoryUsage()
{
long total =_rt.totalMemory()/1024;
long free =_rt.freeMemory()/1024;
long using = total - free;

System.out.println("Total:" + total + "\n" + " Free:" + free + "\n Using:" + using );
}
---
これをXmxなどを設定して実行したところ、以下の結論になりました。

(1)
Xmxを32bit・64bit双方1024mに設定すると、32bitの方がループ内の実行回数が多い。
32bit版では26回実行できるのに、64bit版では18回しか実行できません。
また、このときverbose:gcを使用してOutOfMemory直前のメモリの状況をみると、
32bit版:[GC 977023K->977011K(1040512K), 0.5004429 secs]
64bit版:[GC 664766K->664616K(678144K), 0.0233863 secs]
と、1024mの半分程度しか使用できていません。

(2)
Xmxに加え、Xmsも1024mに双方設定しても、64bit版は改善がみられるものの、
まだ32bit版の方が実行回数が多い。32bit版は変わらず26回ですが、
64bit版は24回です。ですが、メモリの状況は
32bit版:[GC 977013K->977011K(1040512K), 0.0167547 secs]
64bit版:[GC 900282K->898991K(1004928K), 0.1344082 secs]
となり、32bit版にはやはりおよびません。

使用した環境は以下の通りです。
32bit:
Windows Server 2003 R2 Standard Edition
4GB RAM, Intel Xeron E5335
JVM:Java 1.6 Update 3 (jdk-6u3-windows-i586-p.exe)

64bit:
Windows Server 2003 R2 Enterprise Edition
8GB RAM, Intel Xeron E5335
JVM: Java 1.6 Update 3 64bit用(jdk-6u3-windows-amd64.exe)

この結果について、JVMの挙動の違いという結論になるのでしょうか。
個人的には64bit版の方が堅牢に動作してほしいと感じるのですが。

また、その外に64bit版の動作が改善できそうなことや、上記テストの
改善点などあれば、教えていただきたいと思います。

よろしくお願いします。

unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2007-11-11 17:35
引用:

みらーさんの書き込み (2007-11-11 15:45) より:
(1)
Xmxを32bit・64bit双方1024mに設定すると、32bitの方がループ内の実行回数が多い。
32bit版では26回実行できるのに、64bit版では18回しか実行できません。
また、このときverbose:gcを使用してOutOfMemory直前のメモリの状況をみると、
32bit版:[GC 977023K->977011K(1040512K), 0.5004429 secs]
64bit版:[GC 664766K->664616K(678144K), 0.0233863 secs]
と、1024mの半分程度しか使用できていません。


1024MB÷(10,000,000個 * 4 byte/int) = 26.8435456 ですので、32bit版のほうでは、メモリーをほぼフルに使用できていることになります。
(ここでの MB の数え方はシーゲート方式(1,000,000byte)ではありません。)
64bit版で18回(正確には17回?)になる理由が分かりませんが、Xmx の指定を誤っているということはないでしょうか?

引用:

みらーさんの書き込み (2007-11-11 15:45) より:
(2)
Xmxに加え、Xmsも1024mに双方設定しても、64bit版は改善がみられるものの、
まだ32bit版の方が実行回数が多い。32bit版は変わらず26回ですが、
64bit版は24回です。ですが、メモリの状況は
32bit版:[GC 977013K->977011K(1040512K), 0.0167547 secs]
64bit版:[GC 900282K->898991K(1004928K), 0.1344082 secs]
となり、32bit版にはやはりおよびません。


私は64bit版は使ったことがないので、雰囲気は分からないのですが、64bit版は、メモリーを大雑把に使うなどのようなオーバーヘッドがあってもおかしくはないと思いますので、多少、少なくなるのではないでしょうか。

--
unibon {B73D0144-CD2A-11DA-8E06-0050DA15BC86}
みらー
会議室デビュー日: 2002/12/06
投稿数: 6
投稿日時: 2007-11-12 10:07
unibon様ご返答ありがとうございます。

> 64bit版で18回(正確には17回?)になる理由が分かりませんが、Xmx の指定を誤っているということはないでしょうか?

数値を変えてみて実行すると実行できる回数も変わりますので、間違っては
ないと思います。

XmxとXmsをいろいろ変えて実行してみたのですが、64bit版ではXmsの値によって
実行回数が異なるという結果になりました。(前回の数値は1間違えていました。すみません。)

Xms:なし、Xmx:1024m -- 17回
Xms:100m、Xmx:1024m -- 17回
Xms:200m、Xmx:1024m -- 18回
Xms:300m、Xmx:1024m -- 18回
Xms:400m、Xmx:1024m -- 25回
Xms:500m、Xmx:1024m -- 24回
--
Xms:400m、Xmx:2048m -- 45回
Xms:800m、Xmx:2048m -- 52回

32bit版では、Xmx1024mにすると、どういう場合でも変わらず25回です。これは

> 私は64bit版は使ったことがないので、雰囲気は分からないのですが、
> 64bit版は、メモリーを大雑把に使うなどのようなオーバーヘッドがあっても
> おかしくはないと思いますので、多少、少なくなるのではないでしょうか。

ということになるんでしょうか。私の理解ではXmsはヒープサイズの
初期値であり、Xmxの値までは自動的に拡張してくれるものだと思って
いたのですが・・・。

この件に関してご意見・アイディアなどほかにありましたら
よろしくお願いします。
みらー
会議室デビュー日: 2002/12/06
投稿数: 6
投稿日時: 2007-11-15 20:06
ちょっと返答がつかないようですので、
http://forum.java.sun.com/thread.jspa?threadID=5236840
に投稿しました。クロスポストとなりますので、こちらの方は
終了します。返答いただきましたunibonさん、考えていただいた
みなさん、ありがとうございました。
1

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