1.分别创建三个类Test1/Test2/Test3,类Test2继承Test1,Test3与Test2为空类.java
2.给这三个类分别new一个对象,并比较各对象的空间大小.数组
3.结果猜想:若是Test1==Test2>Test3则命题成立;若是Test1>Test2==Test3,则命题不成立.函数
import java.lang.instrument.Instrumentation; import java.lang.reflect.Array; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.IdentityHashMap; import java.util.Map; import java.util.Stack; public class MySizeOf { static Instrumentation inst; public static void premain(String agentArgs, Instrumentation instP) { inst = instP; } public static long sizeOf(Object o) { if(inst == null) { throw new IllegalStateException("Can not access instrumentation environment.\n" + "Please check if jar file containing SizeOfAgent class is \n" + "specified in the java's \"-javaagent\" command line argument."); } return inst.getObjectSize(o); } /** * 递归计算当前对象占用空间总大小,包括当前类和超类的实例字段大小以及实例字段引用对象大小 */ public static long fullSizeOf(Object obj) {//深刻检索对象,并计算大小 Map<Object, Object> visited = new IdentityHashMap<Object, Object>(); Stack<Object> stack = new Stack<Object>(); long result = internalSizeOf(obj, stack, visited); while (!stack.isEmpty()) {//经过栈进行遍历 result += internalSizeOf(stack.pop(), stack, visited); } visited.clear(); return result; } //断定哪些是须要跳过的 private static boolean skipObject(Object obj, Map<Object, Object> visited) { if (obj instanceof String) { if (obj == ((String) obj).intern()) { return true; } } return (obj == null) || visited.containsKey(obj); } private static long internalSizeOf(Object obj, Stack<Object> stack, Map<Object, Object> visited) { if (skipObject(obj, visited)) {//跳过常量池对象、跳过已经访问过的对象 return 0; } visited.put(obj, null);//将当前对象放入栈中 long result = 0; result += sizeOf(obj); Class <?>clazz = obj.getClass(); if (clazz.isArray()) {//若是数组 if(clazz.getName().length() != 2) {// skip primitive type array int length = Array.getLength(obj); for (int i = 0; i < length; i++) { stack.add(Array.get(obj, i)); } } return result; } return getNodeSize(clazz , result , obj , stack); } //这个方法获取非数组对象自身的大小,而且能够向父类进行向上搜索 private static long getNodeSize(Class <?>clazz , long result , Object obj , Stack<Object> stack) { while (clazz != null) { Field[] fields = clazz.getDeclaredFields(); for (Field field : fields) { if (!Modifier.isStatic(field.getModifiers())) {//这里抛开静态属性 if (field.getType().isPrimitive()) {//这里抛开基本关键字(由于基本关键字在调用java默认提供的方法就已经计算过了) continue; }else { field.setAccessible(true); try { Object objectToAdd = field.get(obj); if (objectToAdd != null) { stack.add(objectToAdd);//将对象放入栈中,一遍弹出后继续检索 } } catch (IllegalAccessException ex) { assert false; } } } } clazz = clazz.getSuperclass();//找父类class,直到没有父类 } return result; } }
class Test1 //24 { private int a=1; private long aa=1l; } class Test2 extends Test1 //32 { } class Test3 { } public class TestSize { public static void main(String []args) { System.out.println(MySizeOf.fullSizeOf(new Test1()));//打印Test1对象的大小 System.out.println(MySizeOf.fullSizeOf(new Test2()));//打印Test2对象的大小 System.out.println(MySizeOf.fullSizeOf(new Test3()));//打印Test3对象的大小 } }
1.先打包类MySizeOf.
性能
2.编译执行结果以下:.net