听起来很奇怪,但还是。
假设我有一个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,但实际上我无法计算出我的方法使用了多少内存。
发布于 2014-09-26 17:35:48
测量方法的每次调用的真实大小并不像听起来那么简单,JVM也不支持它。复杂性产生于a)因为JVM被设计为隐藏这种低级细节,以及b) JVM在任何时刻都可能有同一方法的多个变体,这听起来很疯狂,但这也是真的。有时,方法会被内联,或者进行了更多的优化,甚至以一种特殊的方式重新编译,以支持方法在运行时的热交换(!)这可以从根本上改变其运行时大小。
测量调用的方法所使用的堆数量的
由于方法调用不使用堆,因此很容易选择0字节。然而,人们可能想知道方法调用所分配的任何新对象的大小。这个问题是可以回答的,但是对象是跨方法调用和线程共享的。因此,人们必须非常清楚他们想要衡量的是什么,并注意不要计算两次。在Java语言中,有一些库可以给出对象的大小,它们通常通过反射和启发式来工作,或者包装sun.misc.Unsafe来检查指向对象及其数据的指针。例如http://code.google.com/p/javabi-sizeof/。
测量方法的分配率的
YourKit有一个名为here的优秀工具,用于跟踪每个对象在其源点的分配,并报告它们的总大小和速率。对于找出是谁引起GC流失非常有用。
测量每个方法调用使用的堆栈数量的
JVM不会发布此信息,如前所述,它将根据当前活动的优化和正在使用的运行时编译器而有所不同。
另一种选择是使用启发式。例如,计算方法中使用了多少个变量,然后将计数乘以4,得到一个以字节为单位的答案(假设每个变量的大小都是4字节,即一个整数)。显然,这种启发式是有缺陷的,可以改进,但它足够简单,可以给出一个快速和相当有代表性的答案。
发布于 2014-09-26 17:31:46
我在过去使用过以下内容,我发现它很有用:
http://www.javamex.com/classmexer/
https://stackoverflow.com/questions/26055745
复制相似问题