如何测量java方法的内存使用情况

时间:2014-09-26 08:57:15

标签: java performance jvm

听起来很奇怪,但仍然。

想象一下,我有一个java方法

boolean myMethod(Object param1, Object param2) { 
   // here can be some simple calculations. can be some services invokation
   // or calls to DB. doesn't matter
  return someValue;
}

如何衡量JVM用于执行此方法的内存量?实际使用此方法执行多少内存?

是否有任何工具或者我可以在我的方法中添加一些额外的代码以便能够看到用过的内存?

我正在使用JConsole来监控JVM,我也知道我们可以使用java.lang.Runtime来查看freeMemory,但实际上我无法弄清楚我的方法使用此工具的内存量

2 个答案:

答案 0 :(得分:1)

测量方法的每次调用的真实大小并不像听起来那么简单,JVM也不支持它。复杂性来自a)因为JVM被设计为隐藏这种低级细节而b)JVM可能在任何时间点都有相同方法的多个变体,这听起来很疯狂,但也是如此。有时候,这个方法将被内联,或者更加优化或甚至以特殊方式重新编译,以支持方法运行时的热交换(!),从根本上改变其运行时大小。

测量方法调用使用的堆量

鉴于方法调用不使用堆,因此很容易说出0字节。但是,人们可能想知道方法调用分配的任何新对象的大小。这可以回答,但是方法调用和线程之间共享对象。因此,必须非常清楚他们想要衡量的是什么,并注意不要计算两次。有些库可以在Java中提供Object的大小,它们通常可以通过反射和启发式工作,也可以包装sun.misc.Unsafe来检查指向对象及其数据的指针。例如http://code.google.com/p/javabi-sizeof/

衡量方法的分配率

YourKit有一个很好的工具here,用于跟踪源点的每个对象分配并报告其总大小和速率。找出导致GC流失的人非常有用。

测量每次方法调用使用的堆栈数量

JVM不会发布此信息,并且如前所述,它将根据当前处于活动状态的优化和正在使用的运行时编译器而有所不同。

另一种方法是使用启发式方法。计算方法中使用了多少变量并将计数乘以4以得到字节答案(假设每个变量的大小为4个字节,即int)。显然这种启发式方法存在缺陷并且可以改进,但它很简单,可以给出一个快速且具有代表性的答案。

答案 1 :(得分:0)

过去我使用了以下内容,我发现它很有用:

http://www.javamex.com/classmexer/