[ジャワ] オブジェクトのサイズを取得する – オブジェクトのサイズを取得する

我々はすでに知っているように, intなどのプリミティブデータ型のサイズを取得します, ダブル,… Javaで簡単です。, ちょうどInteger.BYTEを呼び出します, Double.BYTE,… 終了した. あなたが特定のクラスのオブジェクトのサイズを取得したい場合でも、簡単ではありません.

オブジェクトのサイズを取得する方法はいくつかあり, この記事で私は財産を所有するクラスを構築する方法をご案内します. この質問の建設ということが、何人が書くと言いました, 私達はちょうどコピーしてのみ使用します, かかわらず、またはへの影響.

我々は、オブジェクトのサイズを考えるだろう、通常のものは、その属性の合計サイズと同等であることをさらに注意してください, しかし、現実には少し異なっています. プロパティの合計サイズに加えて、オブジェクトの大きさがあることが:
プラス 8 ヘッダのバイト.
それは、常に複数のです 8, それ以外の場合は、右のバンパーに切り上げされるべきです 8.

これは、クラスサイズの算出対象であります.

package cachhoc.net.sizeobject;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.HashSet;
import java.util.Set;

public class ObjectSizeCalculator {

	private static final int REFERENCE_SIZE;
	private static final int HEADER_SIZE;
	private static final int LONG_SIZE = 8;
	private static final int INT_SIZE = 4;
	private static final int BYTE_SIZE = 1;
	private static final int BOOLEAN_SIZE = 1;
	private static final int CHAR_SIZE = 2;
	private static final int SHORT_SIZE = 2;
	private static final int FLOAT_SIZE = 4;
	private static final int DOUBLE_SIZE = 8;
	private static final int ALIGNMENT = 8;

	static {
		try {
			if (System.getProperties().get("java.vm.name").toString()
					.contains("64")) {
				// java.vm.name is something like
				// "Java HotSpot(TM) 64-Bit Server VM"
				REFERENCE_SIZE = 8;
				HEADER_SIZE = 16;
			} else {
				REFERENCE_SIZE = 4;
				HEADER_SIZE = 8;
			}
		} catch (Exception ex) {
			ex.printStackTrace();
			throw new AssertionError(ex);
		}
	}

	public static long sizeOf(Object o) throws IllegalAccessException {
		return sizeOf(o, new HashSet());
	}

	private static long sizeOf(Object o, Set visited)
			throws IllegalAccessException {
		if (o == null) {
			return 0;
		}
		ObjectWrapper objectWrapper = new ObjectWrapper(o);
		if (visited.contains(objectWrapper)) {
			// We have reference graph with cycles.
			return 0;
		}
		visited.add(objectWrapper);
		long size = HEADER_SIZE;
		Class clazz = o.getClass();
		if (clazz.isArray()) {
			if (clazz == long[].class) {
				long[] objs = (long[]) o;
				size += objs.length * LONG_SIZE;
			} else if (clazz == int[].class) {
				int[] objs = (int[]) o;
				size += objs.length * INT_SIZE;
			} else if (clazz == byte[].class) {
				byte[] objs = (byte[]) o;
				size += objs.length * BYTE_SIZE;
			} else if (clazz == boolean[].class) {
				boolean[] objs = (boolean[]) o;
				size += objs.length * BOOLEAN_SIZE;
			} else if (clazz == char[].class) {
				char[] objs = (char[]) o;
				size += objs.length * CHAR_SIZE;
			} else if (clazz == short[].class) {
				short[] objs = (short[]) o;
				size += objs.length * SHORT_SIZE;
			} else if (clazz == float[].class) {
				float[] objs = (float[]) o;
				size += objs.length * FLOAT_SIZE;
			} else if (clazz == double[].class) {
				double[] objs = (double[]) o;
				size += objs.length * DOUBLE_SIZE;
			} else {
				Object[] objs = (Object[]) o;
				for (int i = 0; i < objs.length; i++) {
					size += sizeOf(objs[i], visited) + REFERENCE_SIZE;
				}
			}
			size += INT_SIZE;
		} else {
			Field[] fields = o.getClass().getDeclaredFields();
			for (int i = 0; i < fields.length; i++) {
				if (Modifier.isStatic(fields[i].getModifiers())) {
					continue;
				}
				fields[i].setAccessible(true);
				String fieldType = fields[i].getGenericType().toString();
				if (fieldType.equals("long")) {
					size += LONG_SIZE;
				} else if (fieldType.equals("int")) {
					size += INT_SIZE;
				} else if (fieldType.equals("byte")) {
					size += BYTE_SIZE;
				} else if (fieldType.equals("boolean")) {
					size += BOOLEAN_SIZE;
				} else if (fieldType.equals("char")) {
					size += CHAR_SIZE;
				} else if (fieldType.equals("short")) {
					size += SHORT_SIZE;
				} else if (fieldType.equals("float")) {
					size += FLOAT_SIZE;
				} else if (fieldType.equals("double")) {
					size += DOUBLE_SIZE;
				} else {
					size += sizeOf(fields[i].get(o), visited) + REFERENCE_SIZE;
				}
			}
		}
		if ((size % ALIGNMENT) != 0) {
			size = ALIGNMENT * (size / ALIGNMENT) + ALIGNMENT;
		}
		return size;
	}

	private static final class ObjectWrapper {

		private Object object;

		public ObjectWrapper(Object object) {
			this.object = object;
		}

		public boolean equals(Object obj) {
			if (obj == this) {
				return true;
			}
			if ((obj == null) || (obj.getClass() != ObjectWrapper.class)) {
				return false;
			}
			return object == ((ObjectWrapper) obj).object;
		}

		public int hashCode() {
			int hash = 3;
			hash = 47 * hash + System.identityHashCode(object);
			return hash;
		}
	}
}

我々は、試験対象物の大きさの数を実行します:

package cachhoc.net.sizeobject;

import java.util.HashMap;

public class SizeObject {
	// 8 byte header
	int x; // 4 byte
	double y; // 8 byte
	String s; // 0 byte vì s đang null

	public static void main(String[] args) {
		SizeObject so1 = new SizeObject();
		SizeObject so2 = new SizeObject();
		SizeObject so3 = new SizeObject();
		so2.s = "nguyenvanquan";
		so3.s = "nguyenvanquan7826";

		try {

			System.out.println("size of int Object = "
					+ ObjectSizeCalculator.sizeOf(new Integer(5)));
			System.out.println("size of array int[3] = "
					+ ObjectSizeCalculator.sizeOf(new int[] { 1, 2, 3 }));
			System.out.println("size of HashMap = "
					+ ObjectSizeCalculator.sizeOf(new HashMap(512)));

			System.out.println("size of String\"nguyenvanquan7826\" = "
					+ ObjectSizeCalculator.sizeOf(new String(
							"nguyenvanquan7826")));

			System.out.println("size of Object so1 = "
					+ ObjectSizeCalculator.sizeOf(so1));
			System.out.println("size of Object so2 = "
					+ ObjectSizeCalculator.sizeOf(so2));
			System.out.println("size of Object so3 = "
					+ ObjectSizeCalculator.sizeOf(so3));

		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
	}
}

結果は次のようになります:

size of int Object = 16
size of array int[3] = 24
size of HashMap = 32
size of String"nguyenvanquan7826" = 64
size of Object so1 = 24
size of Object so2 = 80
size of Object so3 = 88

リファレンスの記事で: kyryloholodnov.wordpress.com