1

我正在尝试在不同使用级别的 Tomcat Java EE 应用程序中测量我自己的数据结构的内存使用情况。

为了测量内存使用情况,我尝试了两种策略:

  1. 运行时 freeMemory 和 totalMemory:

    System.gc(); //about 20 times
    long start = Runtime.getRuntime().freeMemory();
    
    useMyDataStructure();
    
    long end = Runtime.getRuntime().freeMemory();
    
    System.out.println(start - end);
    
  2. 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));
    }
    

方法1根本不输出可靠的数据。数据没用。

方法 2 输出负值。此外,它告诉getName()我它正在分别输出Code Cache,PS Eden Space和。PS Survivor SpacePS 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 实例的实验。

4

2 回答 2

1

第一个在 java 中调整对象的大小是不平凡的(在这里解释得很好)。

如果您想知道特定对象的大小,至少有 2 个开源库可以为您计算 - java.sizeofjavabi-sizeof

现在,至于您的特定测试- System.gc() 大多被现代(热点)jvm忽略,无论您调用多少次。另外,您的useMyDataStructure()方法是否可能不保留对其创建的对象的引用?在这种情况下,在调用它之后测量空闲内存是不好的,因为任何分配的对象都可能已被清除。

于 2013-07-20T12:24:00.657 回答
1

你可以试试https://github.com/jbellis/jamm,这对我很有用。

于 2013-07-20T12:27:35.310 回答