私は、Javaオブジェクトのサイズを取得する簡単な方法を知りたいですか?また、とにかくC++のsizeof演算子のようなクラスのサイズを取得するには?Javaオブジェクトのサイズを取得する簡単な方法はありますか?
答えて
メモリ内のJavaオブジェクトのサイズを決定するopensource java.SizeOf projectがあります。
Instrumentationインターフェイスには、getObjectSize()メソッドがあります。
ただし、コンポーネントのサブオブジェクトではなく、オブジェクト自体のサイズのみが表示されます。たとえば、すべてのString
オブジェクトが同じサイズであることがわかります。
もう1つの問題は、オブジェクトのサイズが実際に自発的に変更できることです。たとえば、オブジェクトのアイデンティティハッシュコードを取得し、それがGCサイクルで存続する場合、アイデンティティハッシュコード値を格納するために、そのサイズが(少なくとも)4バイト増加します。
「オブジェクト」の大きさを求める問題は、一般的なユーティリティクラス/メソッドは、任意のオブジェクトの抽象化の境界がどこにあるか確実に知ることが不可能であるということです。 Stringクラスほどシンプルなものにも問題があります。 (DOのJava 6のsubstring(...)
を使用して作成されたStringオブジェクトを考えてみましょうあなたでしthis
の一部、または元の文字列の一部、またはその両方?これは、各オブジェクトのサイズは何を意味するのか?などchar[] value
オブジェクト)
このように、net.sourceforge.sizeof
のようなものでは、スペース使用量を完全に正確に計算することはできません。
あなたのプログラムが別のターミナルウィンドウを取得し、実行し、実行している間:
jmap -histo <process id of the java instance you want to debug>
出力ではクラスによって、オブジェクトのインスタンスの数と合計サイズを与えます。たとえば、3 72 java.util.Date
は、それぞれ24バイトを取るメモリ内に3つのDateオブジェクトがあることを意味します。関連する部分があまりにも速くスクロールする場合は、出力をファイルなどにパイプする必要があります。
あるいは、(多くの)詳細については、以下を実行します。
jmap -dump:format=b,file=heap.bin <processid>
jhat heap.bin
その後http://localhost:7000を開きます。ブラウザのヒープ上のオブジェクトを参照することができます。
さらに詳しい情報:
http://docs.oracle.com/javase/6/docs/technotes/tools/share/jmap.html
http://docs.oracle.com/javase/6/docs/technotes/tools/share/jhat.html
私は、オブジェクトが12バイトであっても、日/オラクルJVM上で、それはいつもの方法により8に切り上げます考えて、それがかかります16をメモリに格納します。
のUnsafe
クラスを使用すると、オフセットを取得できます。したがって、オブジェクトがプロセッサのアーキテクチャに従ってアライメントをヒープし、最大フィールドオフセットを計算することを考慮すると、Javaオブジェクトのサイズを測定できます。以下の例では、補助クラスUtilUnsafe
を使用してsun.misc.Unsafe
オブジェクトへの参照を取得します。
private static final int NR_BITS = Integer.valueOf(System.getProperty("sun.arch.data.model"));
private static final int BYTE = 8;
private static final int WORD = NR_BITS/BYTE;
private static final int MIN_SIZE = 16;
public static int sizeOf(Class src){
//
// Get the instance fields of src class
//
List<Field> instanceFields = new LinkedList<Field>();
do{
if(src == Object.class) return MIN_SIZE;
for (Field f : src.getDeclaredFields()) {
if((f.getModifiers() & Modifier.STATIC) == 0){
instanceFields.add(f);
}
}
src = src.getSuperclass();
}while(instanceFields.isEmpty());
//
// Get the field with the maximum offset
//
long maxOffset = 0;
for (Field f : instanceFields) {
long offset = UtilUnsafe.UNSAFE.objectFieldOffset(f);
if(offset > maxOffset) maxOffset = offset;
}
return (((int)maxOffset/WORD) + 1)*WORD;
}
class UtilUnsafe {
public static final sun.misc.Unsafe UNSAFE;
static {
Object theUnsafe = null;
Exception exception = null;
try {
Class<?> uc = Class.forName("sun.misc.Unsafe");
Field f = uc.getDeclaredField("theUnsafe");
f.setAccessible(true);
theUnsafe = f.get(uc);
} catch (Exception e) { exception = e; }
UNSAFE = (sun.misc.Unsafe) theUnsafe;
if (UNSAFE == null) throw new Error("Could not obtain access to sun.misc.Unsafe", exception);
}
private UtilUnsafe() { }
}
特定のクラスのオブジェクトは固定サイズのメモリブロックであるため、オブジェクトサイズを取得することは間違いありません。私はオブジェクトの保持されたサイズを計算するために次のコードを書いた。また、C++の 'sizeof'のようなメソッドを提供します。それはすぐに実行でき、何にも依存しません。コピーして試してみてください!
public class ObjectSizer {
public static final Unsafe us = getUnsafe();
public static boolean useCompressedOops = true;
public static int retainedSize(Object obj) {
return retainedSize(obj, new HashMap<Object, Object>());
}
private static int retainedSize(Object obj, HashMap<Object, Object> calculated) {
try {
if (obj == null)
throw new NullPointerException();
calculated.put(obj, obj);
Class<?> cls = obj.getClass();
if (cls.isArray()) {
int arraysize = us.arrayBaseOffset(cls) + us.arrayIndexScale(cls) * Array.getLength(obj);
if (!cls.getComponentType().isPrimitive()) {
Object[] arr = (Object[]) obj;
for (Object comp : arr) {
if (comp != null && !isCalculated(calculated, comp))
arraysize += retainedSize(comp, calculated);
}
}
return arraysize;
} else {
int objectsize = sizeof(cls);
for (Field f : getAllNonStaticFields(obj.getClass())) {
Class<?> fcls = f.getType();
if (fcls.isPrimitive())
continue;
f.setAccessible(true);
Object ref = f.get(obj);
if (ref != null && !isCalculated(calculated, ref)) {
int referentSize = retainedSize(ref, calculated);
objectsize += referentSize;
}
}
return objectsize;
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static int sizeof(Class<?> cls) {
if (cls == null)
throw new NullPointerException();
if (cls.isArray())
throw new IllegalArgumentException();
if (cls.isPrimitive())
return primsize(cls);
int lastOffset = Integer.MIN_VALUE;
Class<?> lastClass = null;
for (Field f : getAllNonStaticFields(cls)) {
if (Modifier.isStatic(f.getModifiers()))
continue;
int offset = (int) us.objectFieldOffset(f);
if (offset > lastOffset) {
lastOffset = offset;
lastClass = f.getClass();
}
}
if (lastOffset > 0)
return modulo8(lastOffset + primsize(lastClass));
else
return 16;
}
private static Field[] getAllNonStaticFields(Class<?> cls) {
if (cls == null)
throw new NullPointerException();
List<Field> fieldList = new ArrayList<Field>();
while (cls != Object.class) {
for (Field f : cls.getDeclaredFields()) {
if (!Modifier.isStatic(f.getModifiers()))
fieldList.add(f);
}
cls = cls.getSuperclass();
}
Field[] fs = new Field[fieldList.size()];
fieldList.toArray(fs);
return fs;
}
private static boolean isCalculated(HashMap<Object, Object> calculated, Object test) {
Object that = calculated.get(test);
return that != null && that == test;
}
private static int primsize(Class<?> cls) {
if (cls == byte.class)
return 1;
if (cls == boolean.class)
return 1;
if (cls == char.class)
return 2;
if (cls == short.class)
return 2;
if (cls == int.class)
return 4;
if (cls == float.class)
return 4;
if (cls == long.class)
return 8;
if (cls == double.class)
return 8;
else
return useCompressedOops ? 4 : 8;
}
private static int modulo8(int value) {
return (value & 0x7) > 0 ? (value & ~0x7) + 8 : value;
}
private static Unsafe getUnsafe() {
try {
Field f = Unsafe.class.getDeclaredField("theUnsafe");
f.setAccessible(true);
return (Unsafe) f.get(Unsafe.class);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static void main(String[] args) {
System.out.println(retainedSize("Hello Leeeeeeeen"));
}
}
- 1. ActiveMQのキュー長を取得する簡単な方法はありますか?
- 2. 日付を取得する簡単な方法はありますか?
- 3. javascriptオブジェクトのすべてのキーのプロパティを取得する簡単な方法はありますか?
- 4. NSBezierPathを "サイズ変更"する簡単な方法はありますか?
- 5. Object-c/iPhone-OSでオブジェクトの作成者オブジェクトを簡単に取得する方法はありますか?
- 6. Javaでデータベースメタデータを取得する最も簡単な方法は?
- 7. ユーザーの国コードを簡単に取得する方法はありますか?
- 8. (Eclipseを使用して)JavaでJavaScript出力を取得する簡単な方法はありますか?
- 9. Kotlinで_idによってオブジェクトを取得する簡単な方法はありますか?
- 10. Google Financeデータを簡単に取得する方法はありますか?
- 11. Javaでラッパークラスの型を取得する簡単な方法
- 12. 簡単な方法でデータベースから1つのデータのみを取得する方法はありますか?
- 13. フラッシュプロジェクトのサイズを簡単に変更する方法はありますか?
- 14. Scrapyでhttp.responseオブジェクトを取得する最も簡単な方法
- 15. Java - リスト/配列内の各オブジェクトから単一のプロパティを取得する最も簡単な方法は?
- 16. eclipseでJavaプログラムをプロファイルする簡単な方法はありますか?
- 17. JavaでXMLを解析する簡単な方法はありますか?
- 18. R希望の行とそのネイバーを簡単な方法で取得する方法はありますか?
- 19. フレックスプリローダーを隠す簡単な方法はありますか?
- 20. コードを書くことなくsqldatasourceの行数を取得する簡単な方法はありますか?
- 21. "elseif marathon"より簡単な方法はありますか?
- 22. Readlineに代わる簡単な方法はありますか?
- 23. PHPのSQLタイムスタンプからUNIXのタイムスタンプを取得する簡単な方法はありますか?
- 24. Facebookのユーザーから好きなものを簡単に取得する方法はありますか?
- 25. GrailsのリモートサーバからJSONデータセットを取得する簡単な方法はありますか?
- 26. これを行う簡単な方法はありますか?
- 27. BJ concurencyを扱う簡単な方法はありますか?
- 28. API作成の簡単な方法はありますか?
- 29. pandas.Seriesを単調にする簡単な方法はありますか?
- 30. Mapオブジェクトの値を簡単に増やす方法はありますか?
http://stackoverflow.com/questions/52353/in-java-what-is-the-best-way-to-determine-the-size-of-an-object – NAVEED
あなたがより多くのことができます特定。あなたはJavaオブジェクトが使用しているメモリのサイズについて話していますか? –
を参照してください。http://stackoverflow.com/questions/757300/programatically-calculate-memory-occupied-by-a-java-object-including-objects-it – user371320