我正在尝试测量 Tomcat Java EE 应用程序中我自己的数据结构在不同使用级别的内存使用情况。
为了测量内存使用我尝试了两种策略:
运行时 freeMemory 和 totalMemory:
System.gc(); //about 20 times long start = Runtime.getRuntime().freeMemory(); useMyDataStructure(); long end = Runtime.getRuntime().freeMemory(); System.out.println(start - end);
MemoryPoolMXBean.getPeakUsage():
long before = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory(); List<MemoryPoolMXBean> memorymxbeans = ManagementFactory.getMemoryPoolMXBeans(); for(MemoryPoolMXBean memorybean: memorymxbeans){ memorybean.resetPeakUsage(); } useMyDataStructure(); for(MemoryPoolMXBean memorybean: memorymxbeans){ MemoryUsage peak = memorybean.getPeakUsage(); System.out.println(memorybean.getName() + ": " + (peak.getUsed() - before)); }
方法一根本输出可靠的数据。数据没用。
方法 2 输出负值。除此之外是getName()
告诉我它正在输出 Code Cache
, PS Eden Space
, PS Survivor Space
和 PS Old Gen
分别。
我怎样才能在 useMyDataStructure()
之前和之后获得比较一致的内存使用数字?在 Java 中调用?我不想使用 VirtualVM,我更喜欢在 long
中获取数字反对并自己写入文件。
提前致谢。
编辑 1:
useMyDatastructure
上面的例子是为了简化代码。那里到底是什么:
int key = generateKey();
MyOwnObject obj = makeAnObject();
MyContainerClass.getSingleton().addToHashMap(key, obj);
所以本质上我真的在尝试测量 HashMap<Integer, MyOwnObject>
有多少内存在MyContainerClass
需要。我将使用此内存测量来执行一个实验,我会填充 HashMap 和 MyOwnObject 实例。
最佳答案
Java 中所有调整大小的对象中的第一个是非常重要的(如解释得很好 here )。
如果您想知道特定对象的大小,至少有 2 个开源库可以为您计算 - java.sizeof和 javabi-sizeof
现在,至于您的特定测试 - System.gc() 大多被现代(热点)jvms 忽略,无论您调用它多少次。另外,您的 useMyDataStructure()
方法是否可能不保留对其创建的对象的引用?在那种情况下,在调用它之后测量可用内存是不好的,因为任何分配的对象都可能已被清除。
关于java - 测量某个数据结构的内存使用情况,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17762137/