Bee*_*ope 5 java memory string jvm permgen
这是Sun JDK 1.6u21,x64.
我有一个类用于试验perm gen用法,它只包含一个大字符串(512k字符):
public class Big0 {
public String bigString =
"A string with 2^19 characters, should be 1 MB in size";
}
Run Code Online (Sandbox Code Playgroud)
我检查使用烫发根的使用getUsage().toString()上MemoryPoolMXBean为永久生成(在21岁以下称为"PS烫发根"对象,尽管它有不同的版本,或者与不同的垃圾收集器略有不同的名称.
当我第一次引用类时,通过读取来说Big0.class,perm gen跳过~500 KB - 这就是我所期望的,因为字符串的常量池编码是UTF-8,而我只使用ASCII字符.
然而,当我实际创建这个类的实例时,perm gen会跳跃大约2 MB.由于这是1 MB内存中的字符串(每个UTF16字符2个字节,当然没有代理),我很困惑为什么内存使用量是双倍的.
如果我将字符串设为静态,则会产生相同的效果.如果我用最后的,它不能作为编译我超过65535个字节常量池项的上限(不知道为什么最后留下关闭避免了要么 - 认为这是一个加分题).
有任何见解赞赏!
编辑:我还应该指出,这发生在非静态,最终的非静态和静态字符串中,但不适用于最终的静态字符串.由于这已经是字符串常量的最佳实践,也许这主要是学术兴趣.
我认为这是你的测试类的产物。我创建了一个类似的类,然后用javap反编译它。
[eclipse] java 编译器将 String 文字分成块,每个块不超过 64k。用于初始化非常量字段的字节码由将源字符串与一系列 StringBuilder 操作拼凑在一起组成。尽管最终的巨大字符串被保留,但它所组成的大原子占据了常量池中的空间。