那里有类似的问题,但他们似乎避免回答这个具体问题。如何通过 Java 的运行时 api 获取 我的 Java 程序 使用的内存?
这里 的答案表明我可以做这样的事情:
System.out.println("KB: " + (double) (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) / 1024);
但这总是返回相同的数字,无论我运行哪个程序。例如,下面我有一个程序,无论我在地图中放入多少数字,内存使用量都保持不变。
package memoryTest;
import java.util.HashMap;
import java.util.Map;
public class MemoryTest {
static Map<Integer, NewObject> map = new HashMap<Integer, NewObject>();
public static void main(String[] args){
System.out.println("KB: " + (double) (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) / 1024);
fillMemory(25);
System.out.println("KB: " + (double) (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) / 1024);
}
static int j=0;
public static void fillMemory(int i){
for(int k=0; k< 2000; k++)
map.put(j++, new NewObject());
}
public static class NewObject{
long i = 0L;
long j = 0L;
long k = 0L;
}
}
通过 cambecc 的主要方法,输出是:
# 3085, Total: 128516096, Free: 127173744, Diff: 671120
# 173579, Total: 128516096, Free: 110033976, Diff: 671128
# 335207, Total: 128516096, Free: 92417792, Diff: 637544
# 672788, Total: 224198656, Free: 159302960, Diff: 1221520
# 1171480, Total: 224198656, Free: 106939136, Diff: 1221544
# 1489771, Total: 368377856, Free: 227374816, Diff: 1212984
# 1998743, Total: 368377856, Free: 182494408, Diff: 1212984
原文由 Matt 发布,翻译遵循 CC BY-SA 4.0 许可协议
你做得对。获取内存使用情况的方法与您描述的完全相同:
但是你的程序总是返回相同内存使用的原因是因为你没有创建足够的对象来克服
freeMemory
方法的精度限制。尽管它具有字节 _分辨率_,但不能保证freeMemory
需要多 _精确_。 javadoc 说了很多:试试下面的方法,它会创建两 百万
NewObject
实例,并在每次freeMemory
的结果发生变化时打印出来:在我的机器上,我看到如下输出
请注意报告的空闲内存是如何在第 21,437 个对象被实例化之前没有改变的?数字表明
freeMemory
对于我正在使用的 JVM(Java7 Win 64 位),精度刚好超过 2.5MB(尽管如果你运行实验,你会看到这个数字有所不同)。- 编辑 -
此代码与上面相同,但会打印有关内存使用情况的更多详细信息。希望它更清楚 JVM 的内存使用行为。我们在循环中不断分配新对象。在每次迭代期间,如果
totalMemory
或freeMemory
与上一次迭代相同,我们不会打印任何内容。但是,如果其中任何一个发生了变化,我们就会报告当前的内存使用情况。∆
值表示当前使用情况与之前的内存报告之间的差异。在我的笔记本上,我看到以下输出。请注意,您的结果会因操作系统、硬件、JVM 实现等而有所不同:
从这些数据中可以看出几点: