Java 如果不使用探查器,对象有多大
可能重复:Java 如果不使用探查器,对象有多大,java,Java,可能重复: 我在网上找到了这段代码: static Runtime runtime = Runtime.getRuntime(); ... long start, end; Object obj; runtime.gc(); start = runtime.freememory(); obj = new Object(); // Or whatever you want to look at end = runtime.freememory(); System.out.println("Th
我在网上找到了这段代码:
static Runtime runtime = Runtime.getRuntime();
...
long start, end;
Object obj;
runtime.gc();
start = runtime.freememory();
obj = new Object(); // Or whatever you want to look at
end = runtime.freememory();
System.out.println("That took " + (start-end) + "
bytes.");
但是它不是很可靠,你知道如何做得更好吗?JVM将内存分块分配,这样就可以跨线程并发执行。这就是所谓的 TLAB-线程本地分配缓冲区。用于快速分配堆空间,无需同步。编译后的代码有一些指令的“快速路径”,这些指令试图在当前线程的TLAB中碰撞一个高水位线,如果碰撞线落在TLAB特定的限制地址之前,则成功地分配一个对象 如果使用
-XX:-UseTLAB
关闭此选项,您将获得更准确的内存使用信息
public static void main(String... args) {
for (int i = 0; i < 10; i++) {
long used1 = memoryUsed();
new Object();
long used2 = memoryUsed();
System.out.println(used2 - used1);
}
}
public static long memoryUsed() {
return Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
}
publicstaticvoidmain(字符串…参数){
对于(int i=0;i<10;i++){
长时间使用1=已记忆();
新对象();
长时间使用2=记忆已使用();
System.out.println(used2-used1);
}
}
公共静态长内存(){
返回Runtime.getRuntime().totalMemory()-Runtime.getRuntime().freemory();
}
使用默认选项打印
0
0
0
0
0
0
0
0
0
0
使用-XX:-UseTLAB
十六,
16
16
16
16
16
16
16
16
16我在测量物体大小方面有一些经验,我学到的一件事是不要相信探查器。它不会给出实际的测量值,但会对进行估计。为了使这一点非常具体,它在64位虚拟机上100%地误判了引用数组的大小:在实际大小为每个插槽32位的情况下,它猜测的是64位 只要您非常小心地熟悉您的特定配置,并确保获得一致的结果,您的测量方法实际上是很好的。还有一些建议:
System.gc()
s,在它们之间暂停半秒钟左右freemory
,因为堆可能会增长;测量totalMemory()-freemory()
您可以序列化对象并查看保存了多少数据。显然,这将不同于内存中的对象大小!“关于如何做得更好有什么想法吗?”有什么好的理由吗?请参阅以获得更可靠的方法。请在您的问题中解释您想用此代码做什么哇,这么多批评者…此代码仅用于了解VM内部发生的情况,而不是任何生产或项目代码的一部分。这确实更好,Thx.说到信任,
System.gc()
肯定是我不信任的:)@MiljenMikic你是根据这种微基准的实际经验说的吗?我从未遇到过任何来自System.gc()
I的不确定性,它在不同的实现中有所不同,但在一个固定的环境中是完全稳定和可预测的。不是使用这种基准测试,而是通常在其他应用程序中。我曾在两个项目中尝试依赖System.gc()
,但在跟踪内存消耗后放弃了,因为它确实有“自己的想法”。这是Sun JDK Java 1.6.0xx的实现。是的,System.gc()
不是解决实时生产应用程序内存问题的工具。