一个Java Integer对象分配了多少内存?如何找出任何自定义对象的这个值?

8

如何正确地测量堆内存中应该用于创建某种类型的新对象的内存量(让我们以整数为例进行讨论)?

这个值能否在不进行实验的情况下计算出来?在这种情况下有哪些规则?这些规则是否严格指定在某个地方,还是可能因JVM而异?


它们不会因机器而异,但如果这是你所问的,Java中没有sizeof运算符。 - Cratylus
3个回答

14

这可能因JVM而异。

你可能会喜欢Oracle工程师这篇博客文章

在32位Hotspot JVM中的Java Integer的情况下,32位有效负载(一个Integer.value字段)附带有96个额外的位:一个标记,一个类,一个字的对齐填充,总共为128位。此外,如果世界上有(例如)六个引用指向此整数(线程加堆),这些引用还会占用192位,总计为320位。在64位机器上,目前一切都是两倍大:对象大小达到256位(现在包括96位的填充),其他地方为384位。相比之下,六个未装箱的基本整数副本占用192位。


1
你可能需要查看Java instrumentation来找到答案。这里是一个例子。
在你的情况下,我相信你想从应用程序内部找到对象的大小,你需要将Instrumentation对象设置为全局可用(static),这样你就可以从应用程序中访问它。 代码从链接中复制:
public class MyAgent {
  private static volatile Instrumentation globalInstr;
  public static void premain(String args, Instrumentation inst) {
    globalInstr = inst;
  }
  public static long getObjectSize(Object obj) {
    if (globalInstr == null)
      throw new IllegalStateException("Agent not initted");
    return globalInstr.getObjectSize(obj);
  }
}

然而,我相信您将能够找到仅对象的大小(不是原始类型,您也不需要找出它们,因为您已经知道它们 :-))

请注意,getObjectSize()方法不包括由传入对象引用的其他对象使用的内存。例如,如果对象A引用对象B,则对象A报告的内存使用情况仅包括引用对象B所需的字节(通常为4个字节),而不是实际对象。

要获取对象的“深度”内存使用计数(即包括“子对象”或“主”对象引用的对象),则可以使用可从this网站下载的Classmexer代理进行beta下载。


0

在Java中这并不容易实现:sizeof不存在,而其他替代方案,例如将对象序列化为字节流并查看结果流的长度,在某些情况下(例如字符串)无法正常工作。

但是,可以参考这个相当复杂的实现,使用对象图。


1
你可能错误地在你的回答中链接了这个帖子 :) - Roman
@Roman,糟糕,错误已经被编辑 :) - Frédéric Hamidi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接