为什么 jmap -permstat 会报告超过使用的 MaxPermSize 字节数?
Why would jmap -permstat report more than MaxPermSize bytes used?
我获取了 JVM 的 jmap -permstat
输出(报告为版本 24.76-b04),它报告了以下总计:
total = 5190 76930 1031431696 N/A alive=1, dead=5189 N/A
应该是条目数,类 使用此信息,用于元数据和活动信息的字节数。
现在,我想知道为什么它会报告 1031431696 bytes
,当我用 -XX:MaxPermSize=256m
启动我的 VM 时只差一个千兆字节。有人可以阐明这个数字是如何计算的吗?
不知道它是否相关,但这是使用 Rhino,其中 ~3k 个条目是 DefiningClassLoader
s。
我稍微看了看 jmap -permstat
实现的代码。使用的字节数是基于 classloader 加载的不同类型数据(方法、字段、接口等)的大小的估计值。
为加载的 class 计算大小的顶级方法是 sun.jvm.hotspot.tools.PermStat.computeSize
:
private long computeSize(InstanceKlass k) {
long size = 0L;
// the InstanceKlass object itself
size += k.getObjectSize();
// Constant pool
ConstantPool cp = k.getConstants();
size += cp.getObjectSize();
size += objectSize(cp.getCache());
size += objectSize(cp.getTags());
// Interfaces
size += arraySize(k.getLocalInterfaces());
size += arraySize(k.getTransitiveInterfaces());
// Inner classes
size += objectSize(k.getInnerClasses());
// Fields
size += objectSize(k.getFields());
// Methods
ObjArray methods = k.getMethods();
int nmethods = (int) methods.getLength();
if (nmethods != 0L) {
size += methods.getObjectSize();
for (int i = 0; i < nmethods; ++i) {
Method m = (Method) methods.getObjAt(i);
size += m.getObjectSize();
size += objectSize(m.getConstMethod());
}
}
// MethodOrdering - an int array that records the original
// ordering of methods in the class file
size += arraySize(k.getMethodOrdering());
return size;
}
我的猜测是这种估计在你的情况下非常失败。如果不详细检查 JVM 版本的对象大小计算并结合应用程序中加载的 classes 的特性,很难说失败的原因。
此外,Troubleshooting Guide for Java SE 6 with HotSpot VM 提到该值是一个近似值。
最重要的是,对字节使用值持保留态度。
我获取了 JVM 的 jmap -permstat
输出(报告为版本 24.76-b04),它报告了以下总计:
total = 5190 76930 1031431696 N/A alive=1, dead=5189 N/A
应该是条目数,类 使用此信息,用于元数据和活动信息的字节数。
现在,我想知道为什么它会报告 1031431696 bytes
,当我用 -XX:MaxPermSize=256m
启动我的 VM 时只差一个千兆字节。有人可以阐明这个数字是如何计算的吗?
不知道它是否相关,但这是使用 Rhino,其中 ~3k 个条目是 DefiningClassLoader
s。
我稍微看了看 jmap -permstat
实现的代码。使用的字节数是基于 classloader 加载的不同类型数据(方法、字段、接口等)的大小的估计值。
为加载的 class 计算大小的顶级方法是 sun.jvm.hotspot.tools.PermStat.computeSize
:
private long computeSize(InstanceKlass k) {
long size = 0L;
// the InstanceKlass object itself
size += k.getObjectSize();
// Constant pool
ConstantPool cp = k.getConstants();
size += cp.getObjectSize();
size += objectSize(cp.getCache());
size += objectSize(cp.getTags());
// Interfaces
size += arraySize(k.getLocalInterfaces());
size += arraySize(k.getTransitiveInterfaces());
// Inner classes
size += objectSize(k.getInnerClasses());
// Fields
size += objectSize(k.getFields());
// Methods
ObjArray methods = k.getMethods();
int nmethods = (int) methods.getLength();
if (nmethods != 0L) {
size += methods.getObjectSize();
for (int i = 0; i < nmethods; ++i) {
Method m = (Method) methods.getObjAt(i);
size += m.getObjectSize();
size += objectSize(m.getConstMethod());
}
}
// MethodOrdering - an int array that records the original
// ordering of methods in the class file
size += arraySize(k.getMethodOrdering());
return size;
}
我的猜测是这种估计在你的情况下非常失败。如果不详细检查 JVM 版本的对象大小计算并结合应用程序中加载的 classes 的特性,很难说失败的原因。
此外,Troubleshooting Guide for Java SE 6 with HotSpot VM 提到该值是一个近似值。
最重要的是,对字节使用值持保留态度。