计算对象的“权重”,如何

时间:2012-06-28 20:19:22

标签: java memory-management garbage-collection

  

可能重复:
  In Java, what is the best way to determine the size of an object?

假设您有一个数据结构,允许您向其添加数据,比如列表:

List<KeyValuePair>

由于系统的客户端实际上添加了内容...在某些时候,JVM将耗尽内存,这只是一个问题,何时会发生这种情况。最好定期将包含此列表的对象保存到磁盘,然后将gc保存到其余部分。

使用Java,是否可以估计对象现在占用多少内存?

3 个答案:

答案 0 :(得分:3)

getObjectSize()方法可能是您正在寻找的方法 引自Interface Instrumentation文档:

  

getObjectSize(Object objectToSize)
  返回指定对象占用的存储量的特定于实现的近似值。

答案 1 :(得分:3)

您正在寻找java.lang.instrument.Instrumentation.getObjectSize(Object object)

文档:

  

返回特定于实现的近似量   指定对象占用的存储空间。结果可能包括一些   或者所有对象的开销,因此可用于比较   在实现中但不在实现之间。估计   可能会在单次调用JVM期间发生更改。

http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/instrument/Instrumentation.html#getObjectSize%28java.lang.Object%29

但是为了能够使用它:

  

访问Instrumentation接口实例的唯一方法是   以指示代理类的方式启动JVM -   看包装规格。 Instrumentation实例已通过   到代理类的premain方法。一旦代理人获得了   在Instrumentation实例中,代理可以调用​​实例上的方法   在任何时候。

良好的实施样本: http://www.javalobby.org/java/forums/t19309.html

答案 2 :(得分:1)

您可以通过制作大量相同的对象并测量所占用的内存来实现。我已经多次使用这种技术,具有稳定,可重复的结果。在大纲中,

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。这种方法的优点在于它会自动考虑对象的有效堆影响,并考虑到所有因素。当然,在信任之前,您应该检查它在设置中是否可靠。