【问题标题】:Memory usage of an object [duplicate]对象的内存使用情况[重复]
【发布时间】:2013-02-12 10:56:07
【问题描述】:

如果我有一个对象,并且想粗略估计对象的大小与其组件的大小相比,我可以这样做吗?

Object 有一个 int 字段和一个 float 字段。因此,该对象的空间使用量是对该对象的引用大小(8)字节 + 两个原始值 16+16 的大小,这使我需要 40 字节或 25% 的额外空间。

【问题讨论】:

  • 对象也将引用它的基类。如果它存在于对象中(不在函数中),则引用的大小和大小将很重要。
  • 由于 OOP 压缩(google it),引用的大小主要是 4 个字节。一个空的Object 占用 16 个(或者是 24 个?)字节的纯开销(监视器、类型标记、各种标志)。总数再次与 8 字节边界字对齐。
  • 找出答案的最佳方法是通过分配一个较大的对象数组并比较前后的内存使用情况来进行测量。您还必须注意 GC-ing,并让自己相信结果对于您的 JVM 和设置是确定性的。

标签: java object memory space


【解决方案1】:

检查对象大致大小的一种方法是创建该对象的许多实例并检查前后的内存。要获得更准确的数字,您可以使用特定的 JVM 参数:

-verbose:gc -XX:-UseTLAB
  • verbose:gc 确保在测量过程中不会发生 GC
  • -XX:-UseTLAB 要求 JVM 不要以块的形式分配内存(否则它会这样做以提高效率)。关闭该选项可提供更准确、更稳定的结果。

然后您可以通过在分配前后调用Runtime.getRuntime().freeMemory(); 来监控内存使用情况。

请注意,添加字段并不一定会增加内存使用量。例如,在热点 7 64 位上,一个对象在内存中占用 16 个字节,但向该对象添加一个 int 字段不会改变大小(即,拥有一个 int 字段的对象在该 JVM 上也是 16 字节)。这是由于内存对齐限制。

【讨论】:

  • +1 我已经看到Instrumentation 技术给出的结果不如这种“粗略”的技术准确。一方面,它没有考虑 OOP 压缩。
  • @MarkoTopolnik 这种方法的主要问题是,根据您分配对象的顺序,结果可能会有所不同,这是我从未完全理解的。但是通过以不同的顺序进行多次测试,您通常可以得到准确的结果。
  • 我将其称为此方法的另一个优势 --- 显示真正的问题是什么。对象不是struct,所以谁知道发生了什么。
【解决方案2】:

您可以使用 java.lang.instrumentation 包:

http://docs.oracle.com/javase/7/docs/api/java/lang/instrument/Instrumentation.html

它有一个方法可以用来获取对象大小的实现特定的近似值,以及与对象相关的开销。

谢尔盖链接的答案有一个很好的例子,我将在这里重新发布,但你应该已经从他的评论中看到了:

import java.lang.instrument.Instrumentation;
public class ObjectSizeFetcher {
private static Instrumentation instrumentation;

public static void premain(String args, Instrumentation inst) {
    instrumentation = inst;
}

public static long getObjectSize(Object o) {
    return instrumentation.getObjectSize(o);
}
}

使用getObjectSize:

public class C {
private int x;
private int y;

public static void main(String [] args) {
    System.out.println(ObjectSizeFetcher.getObjectSize(new C()));
}

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-08
    • 2014-07-30
    • 2016-01-20
    • 2010-11-26
    • 2012-01-13
    • 1970-01-01
    • 2022-01-12
    相关资源
    最近更新 更多