测量某个数据结构的内存使用情况

时间:2013-07-20 12:11:38

标签: java tomcat memory measurement

我正在尝试在不同使用级别的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));
    }
    
  3. 方法1根本不会输出可靠数据。这些数据毫无用处。

    方法2输出负值。除此之外,getName()告诉我它分别输出Code CachePS Eden SpacePS Survivor SpacePS Old Gen

    如何在Java useMyDataStructure()调用之前和之后获取一些一致的内存使用数?我不想使用VirtualVM,我更喜欢在long对象中捕获数字并将其写入文件。

    提前致谢。


    编辑1:

    上述示例中的

    useMyDatastructure试图简化代码。那是什么:

            int key = generateKey();
            MyOwnObject obj = makeAnObject();
            MyContainerClass.getSingleton().addToHashMap(key, obj);
    

    所以从本质上讲,我真的想测量HashMap<Integer, MyOwnObject>MyContainerClass占用的内存量。我将使用此内存测量来执行实验,其中我将填充HashMap和MyOwnObject实例。

2 个答案:

答案 0 :(得分:1)

java中所有大小调整对象中的第一个都是非常重要的(正如非常好地解释here)。

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

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

答案 1 :(得分:1)

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