リストなど、データを追加できるデータ構造があるとします。
List<KeyValuePair>
システムのクライアントが実際にコンテンツを追加すると、ある時点で JVM がメモリ不足になります。問題は、これがいつ発生するかだけです。このリストを含むオブジェクトをディスクなどに定期的に保存するとよいでしょうgc
。
Java を使用して、オブジェクトが現在使用しているメモリ量を見積もることはできますか?
リストなど、データを追加できるデータ構造があるとします。
List<KeyValuePair>
システムのクライアントが実際にコンテンツを追加すると、ある時点で JVM がメモリ不足になります。問題は、これがいつ発生するかだけです。このリストを含むオブジェクトをディスクなどに定期的に保存するとよいでしょうgc
。
Java を使用して、オブジェクトが現在使用しているメモリ量を見積もることはできますか?
あなたは探しているjava.lang.instrument.Instrumentation.getObjectSize(Object object)
ドキュメンテーション:
指定されたオブジェクトによって消費されるストレージの量の実装固有の概算を返します。結果には、オブジェクトのオーバーヘッドの一部またはすべてが含まれる可能性があるため、実装内では比較に役立ちますが、実装間では役立ちません。見積もりは、JVMの1回の呼び出し中に変更される可能性があります。
しかし、それを使用できるようにするために:
Instrumentationインターフェースのインスタンスにアクセスする唯一の方法は、エージェントクラスを示す方法でJVMを起動することです。パッケージの仕様を参照してください。Instrumentationインスタンスは、エージェントクラスのpremainメソッドに渡されます。エージェントがInstrumentationインスタンスを取得すると、エージェントはいつでもインスタンスのメソッドを呼び出すことができます。
優れた実装サンプル: http ://www.javalobby.org/java/forums/t19309.html
メソッドは、getObjectSize()
あなたが探しているものかもしれません。インターフェイス インストルメンテーションのドキュメント
からの引用:
getObjectSize(Object objectToSize)
指定されたオブジェクトによって消費されるストレージ量の実装固有の概算を返します。
同じオブジェクトをたくさん作って、消費したメモリを測定することでそれを行うことができます。私はこの手法を数回使用しており、安定した再現性のある結果が得られています. 概要では、
public static void main(String[] args) {
final Object[] a = new Object[10000];
final long startMem = memTaken();
for (int i = 0; i < a.length; i++) a[i] = new Object();
System.out.println((memTaken() - startMem) / a.length);
a.hashCode();
}
static long memTaken() {
final Runtime rt = getRuntime();
try {
rt.gc(); Thread.sleep(50);
rt.gc(); Thread.sleep(50);
} catch (InterruptedException e) {}
final long memTaken = rt.totalMemory() - rt.freeMemory();
System.out.println("Mem taken " + memTaken);
return memTaken;
}
これにより、私のマシンでは24という数値が確実に生成されます。このアプローチの利点は、オブジェクトの効果的なヒープへの影響が自動的に考慮され、すべてが考慮されることです。もちろん、信頼する前に、セットアップで信頼できることを確認する必要があります。