Java 在两个连续调用之间初始化数组时,Runtime.freemory()返回两个连续调用之间的变量值?
为什么我得到以下代码的变量输出:Java 在两个连续调用之间初始化数组时,Runtime.freemory()返回两个连续调用之间的变量值?,java,memory-management,runtime,Java,Memory Management,Runtime,为什么我得到以下代码的变量输出: Runtime rt = Runtime.getRuntime(); long x,y; x = rt.freeMemory(); char z[] = new char[Index]; y = rt.freeMemory(); System.out.println("Difference = " + (x-y)) 对于较小的索引值(=100000),输出为零。值为200016。每加一次零,输出为2000016 这怎么可能。 [编辑]我的目标是在内存中查找数
Runtime rt = Runtime.getRuntime();
long x,y;
x = rt.freeMemory();
char z[] = new char[Index];
y = rt.freeMemory();
System.out.println("Difference = " + (x-y))
对于较小的索引值(=100000),输出为零。值为200016。每加一次零,输出为2000016
这怎么可能。
[编辑]我的目标是在内存中查找数据对象的大小(代码中使用-就像这里我使用了索引大小的Char z[])。我写System.gc()
,您可以看到差异
Runtime rt = Runtime.getRuntime();
long x,y;
System.gc();
x = rt.freeMemory();
char z[] = new char[1000];
y = rt.freeMemory();
System.out.println("X = " + (x));
System.out.println("Y = " + (y));
System.out.println("Difference = " + (x-y));
输出
X = 16179672
Y = 16085904
Difference = 93768
您的假设似乎是,如果您有n个字节的可用内存,并分配m个字节,那么之后您将有n-m个字节的可用内存 这是一个合理的假设,但在异步垃圾收集器存在的情况下,它是错误的,异步垃圾收集器会或不会按照它们认为合适的方式执行内存压缩jsut 即使您花费数年时间研究某个JVM的行为,并积累了深刻的智慧和知识,可以预测分配对freeMemory()结果的影响,但当您切换到另一个JVM或仅更新当前JVM时,这些知识可能突然变得毫无价值
因此,相信我们这些年长的人,把
Runtime.freemory()
看作是一种有趣的随机数生成器。freemory()
并非如此精确,也没有考虑GC等。如果需要测量内存消耗,请使用类似的工具。JVM是一个复杂的野兽。据我们所知,它可能正在优化整个char z[]=new char[Index];
因为它实际上没有在其他地方使用。所以rt.freeMemory()的结果永远不可信?是吗?最小计数(内存消耗的最小值)是多少我可以检查最多和通过哪个方法调用?我永远不会在您的程序中依赖它。即使在同一个程序的运行中,它的准确性也会有很大差异,更不用说JVM配置选项了。如果您告诉我们您实际想对这些数据做什么,这会有所帮助。如果您的目标只是提前为您的程序进行内存测量,那么使用上面链接的内存测量工具,但是在生产代码中间没有可靠的快速测量对象内存消耗的方法。<代码> St.GC.()<代码>不能保证垃圾回收——它只是“鼓励”。GC可能会发生。依赖它是不好的,它肯定不会得到真正准确的结果。但你可以看到区别。我找到了动机,我也尝试了50多次执行代码,然后我发布了答案。你很幸运。你不能依赖GC获得准确的数据。无论如何,char[]
数组占用12字节的开销,然后每个字符占用2字节的开销,四舍五入为8的倍数。您的数据表明GC中正在进行其他工作。使用此技术无法获得准确的结果。@LouisWasserman当前的情况是,您无法获得准确的结果。但是作为一个整体,获取0
的问题结果已解决这是我的观点。它不会总是被解决。System.gc()
不会总是触发垃圾收集——这只是对JVM的一个建议。