Jdk版本:1.6.0_38
运行参数:-XX:PermSize=4M -XX:MaxPermSize=4M -verbose -verbose:gc-XX:+UseConcMarkSweepGC -XX:+CMSClassUnloadingEnabled
程序代码:
public static void main(String[] args) {
Random rnd = new Random();
List<String> interned = newArrayList<String>();
for (;;) {
int length = rnd.nextInt(100);
StringBuilder builder = newStringBuilder();
String chars ="abcdefghijklmnopqrstuvwxyz";
for ( int i = 0; i < length; i++) {
builder.append(chars.charAt(rnd.nextInt(chars.length())));
}
interned.add(builder.toString().intern());
}
}
运行结果:
导致永久内存区溢出,有两种可能性:
1 String.intern(String)
这个方法创建的String是在永久内存堆上。当创建许多可reachable的这种String时,可能会导致永久内存区的溢出。
2
通过类加载器创建内部的创建的内部类描述符也是在永久内存堆上。如果你的类动态的加载了许多的类,并且这些对象不能执行gc,也有可能会导致永久内存区的溢出。