可能重复:
在 Java 中,确定对象大小的最佳方法是什么?
假设您有一个允许您向其中添加数据的数据结构,例如一个列表:
List<KeyValuePair>
由于系统的客户端实际上添加了内容......在某些时候,JVM会耗尽内存,这只是何时发生的问题。定期将包含此列表的对象保存到磁盘和gc
其余部分会很好。
使用 Java,是否可以估计一个对象现在占用了多少内存?
可能重复:
在 Java 中,确定对象大小的最佳方法是什么?
假设您有一个允许您向其中添加数据的数据结构,例如一个列表:
List<KeyValuePair>
由于系统的客户端实际上添加了内容......在某些时候,JVM会耗尽内存,这只是何时发生的问题。定期将包含此列表的对象保存到磁盘和gc
其余部分会很好。
使用 Java,是否可以估计一个对象现在占用了多少内存?
该getObjectSize()
方法可能是您正在寻找的。来自Interface Instrumentation文档
的引用:
getObjectSize(Object objectToSize)
返回指定对象消耗的存储量的特定于实现的近似值。
你正在寻找java.lang.instrument.Instrumentation.getObjectSize(Object object)
文档:
返回指定对象消耗的存储量的特定于实现的近似值。结果可能包括对象的部分或全部开销,因此对于实现内的比较有用,而不是实现之间的比较。估计值可能会在 JVM 的单次调用期间发生变化。
但为了能够使用它:
访问 Instrumentation 接口实例的唯一方法是以指示代理类的方式启动 JVM - 请参阅包规范。Instrumentation 实例被传递给代理类的 premain 方法。一旦代理获得了 Instrumentation 实例,代理就可以随时调用实例上的方法。
您可以通过制作许多相同的对象并测量所占用的内存来做到这一点。我现在已经多次使用这种技术,结果稳定、可重复。在大纲中,
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。这种方法的优点是它会自动考虑对象的有效堆影响,并考虑所有因素。当然,在信任它之前,您应该检查它在您的设置中是否可靠。