2010-06-01 31 views
7

我想测量我的Java应用程序的内存分配数据,即分配的所有对象的大小的总和。由于对象分配是在年轻一代完成的,这似乎是正确的地方。如何衡量年轻一代收集的记忆的总和?

我知道jconsole,我知道JMX bean,但我找不到合适的变量......目前我们正在解析gc日志输出文件,但这非常困难。理想情况下,我们想通过JMX来测量它...

我该如何得到这个值?

查德威克的评论后附加信息:

我想知道我的应用程序使用多少内存。这是一个运行在JBoss Appserver中的相当大的软件。每4周有一个新版本的软件,我们需要比较旧版本和新版本之间的内存消耗。在特定时间比较旧一代的现值是不够的。知道分配多少/多少内存非常有用。由于许多物体正在年轻一代收集,我需要在那里进行测量。

在此期间,我对此有一个估计。我会将其作为答案发布。

感谢, 马塞尔

+11

不是Facebook收集的年轻一代的记忆? * duck and runs ... * – 2010-06-01 09:19:11

+0

非常好;-)但是这并不便于确定分配的大小 – Marcel 2010-06-01 15:26:29

+0

您是问在一段时间内分配了多少内存或者在特定的运行期间回收了多少内存? GC?看起来你的头衔要求一个,但问题要求另一个,并且我认为GC可能会在一段时间内运行多次,因此确定收集的最终内存不会给出准确的“总分配”总和。是的,这可以减轻,但一个用例会有助于澄清。 – Chadwick 2010-08-31 00:39:08

回答

1

这是我对估计的想法。它基本上返回“年轻一代x年龄的数量”的价值。这并不完美,但对我的用例来说效果很好。

public long getYoungGenAllocatedMB() { 
    long youngMaxMemory; 
    long youngUsedMemory; 
    long youngCollectionCount; 

    List<MemoryPoolMXBean> beans = ManagementFactory.getMemoryPoolMXBeans(); 
    for (MemoryPoolMXBean bean : beans) { 
    if ("Par Eden Space".equals(bean.getName())) { 
     MemoryUsage usage = bean.getUsage(); 
     youngMaxMemory = usage.getMax(); 
     youngUsedMemory = usage.getUsed(); 
     break; 
    } 
    } 

    List<GarbageCollectorMXBean> gBeans = ManagementFactory.getGarbageCollectorMXBeans(); 
    for (GarbageCollectorMXBean bean : gBeans) { 
    if ("ParNew".equals(bean.getName())) { 
     youngCollectionCount = bean.getCollectionCount(); 
     break; 
    } 
    } 

    return (youngCollectionCount * youngMaxMemory + youngUsedMemory)/1024/1024; 
} 

感谢所有其他的海报!

马塞尔

+0

从Java7u4开始,可以使用GarbageCollectorMXBean注册监听器。这工作相当好,例如:http://www.fasterj.com/articles/gcnotifs.shtml – Marcel 2012-08-10 09:02:27

1

Yourkit分析器提供了内存使用情况良好的击穿。还有在http://www.yourkit.com/download/index.jsp

+0

我知道各种分析器。它们都不能用于生产环境。但我想测量生产! – Marcel 2010-06-01 09:55:50

+0

事实上,我之所以建议它,是因为我在大量网站的生产环境中使用它,影响最小 – Ceilingfish 2010-06-01 10:14:45

+0

好的,但它不可用,因为我们需要> 30个许可证。我想用更便宜的解决方案来代替。 – Marcel 2010-06-01 10:51:53

3
+0

我知道JMX远程处理。我知道Memory-MBeans。但是我在哪里可以得到所需的值:所有分配对象大小的总和? – Marcel 2010-06-01 13:14:36

2

JDK,您可以简单地使用-verbose:gc -Xloggc:gc.log启用GC日志记录并分析文件。或者,如果您只是偶尔需要总金额,请通过Tagtraum获得GCViewer,计算您正在查找的号码。

+0

是的,我知道这两种工具。没有解决它。我在我的应用程序运行时需要这个值。 – Marcel 2010-06-02 07:52:13

1

我还没有亲自使用它,但你有没有试过jmap

-heap选项打印出明智的堆使用情况。

其与jdk捆绑在一起的工具,所以它的免费,可能没有很多开销。

+0

是的,我知道jmap。但我想确定我的Java应用程序本身的值。所以jstat是没有选择的。 – Marcel 2010-08-26 16:34:56

1

这段代码怎么样,它给了你在所有空间中使用的字节总数(eden,survivor,old & perm),这几乎就是你的JVM实例使用的所有内存。

public static void main(String[] args) { 
    for (GarbageCollectorMXBean bean : ManagementFactory.getGarbageCollectorMXBeans()) { 
     if (bean instanceof com.sun.management.GarbageCollectorMXBean) { 
      com.sun.management.GarbageCollectorMXBean internal = (com.sun.management.GarbageCollectorMXBean) bean; 
      Runtime.getRuntime().gc(); 
      GcInfo gcInfo = internal.getLastGcInfo(); 
      for (Map.Entry<java.lang.String,java.lang.management.MemoryUsage> e : gcInfo.getMemoryUsageBeforeGc().entrySet()) { 
       System.out.println(e.getKey() + ": " + e.getValue()); 
      } 
     } 
    } 
} 
+0

没错,但我必须调查内存使用情况,当我的民意调查之间有2个或更多gcs时,我会想念他们。我想到了“基于事件的”机制(获得每个gc的通知)或现有的价值,该价值持有年轻一代分配的总额。 – Marcel 2010-09-05 16:19:31