background image

如何实时得到 Java object 占用的空间

Java 有一个很好的地方就是 java 的垃圾收集机制,这个机制集成于 jvm 的,对程序员
来说是隐藏且不透明的。这种情况下,如何得到某个对象消耗的内存呢?
    曾 经 看 到 过 有 人 用 以 下 方 法 来 计 算 : 在 生 成 该 object 的 前 后 都 调 用
java.lang.Runtime.freeMemory()方法,然后看两者之差即为该 object 消耗的内存量。
  这种方法的代码是:
  long totalMem = java.lang.Runtime.freeMemory();
  Object myBigObject = null;
    System.out.println("You   just   got   rid   of   "   +   totalMem   - 
java.lang.Runtime.freeMemory());

  这种想法是对的,但是实际上,jvm 的 freememory 往往不能正确反应实际的 free 
memory。比如在 jvm 要进行垃圾收集的时候,free memory 就会缩小。而如果决定垃
圾 收 集 的 时 间 发 生 在 该 object 生 成 之 后 , 而 在 第 二 次 调 用
java.lang.Runtime.freeMemory()之前,那么就会错误地增加该 object
  消耗地内存量。
  在 java 专家 By Tony Sintes 的文章"Discover how much memory an object 
consumes " 里面提到了应该用 Runtime.getRuntime().totalMemory();并且计算两
次之差来得到消耗的内存量。
  By Tony Sintes 的源代码:
  public class Memory {
  private final static int _SIZE = 500;
  public static void main( String [] args ) throws Exception {
  Object[] array = new Object[_SIZE];
  Runtime.getRuntime().gc();
  long start = Runtime.getRuntime().totalMemory();
  for (int i = 0; i < _SIZE; i++) {
  array[i] = new Object();
  }
  Runtime.getRuntime().gc();
  long end = Runtime.getRuntime().totalMemory();
  long difference = ( start - end ) / _SIZE;
  System.out.println( difference + " bytes used per object on

  average" );

  }
  }