【问题标题】:Will Java's interned strings be GCed?Java 的实习字符串会被 GC 处理吗?
【发布时间】:2013-03-16 17:46:29
【问题描述】:

在跟踪可能的内存泄漏时,我遇到了以下现象。 Java 7 回收实习字符串或 jmap 是否不精确?

# jmap -heap 9724 | grep 实习 正在附加到进程 ID 9724,请稍候... 调试器连接成功。 检测到服务器编译器。 JVM版本是23.3-b01 10526 个实习字符串,占用 880048 个字节。 # jmap -heap 9724 | grep 实习 正在附加到进程 ID 9724,请稍候... 调试器连接成功。 检测到服务器编译器。 JVM版本是23.3-b01 10514 个实习字符串,占用 878984 个字节。 # jmap -heap 9724 | grep 实习 正在附加到进程 ID 9724,请稍候... 调试器连接成功。 检测到服务器编译器。 JVM版本是23.3-b01 10519 个实习字符串,占用 879720 字节。

环境: Linux 版本 2.6.32-220.23.1.el6.centos.plus.x86_64 (mockbuild@c6b5.bsys.dev.centos.org) (gcc 版本 4.4.6 20110731 (Red Hat 4.4.6-3) (GCC) ) #1 SMP 2012 年 6 月 19 日星期二 04:14:37 BST

java版本“1.7.0_07” Java(TM) SE 运行时环境 (build 1.7.0_07-b10) Java HotSpot(TM) 64 位服务器 VM(内部版本 23.3-b01,混合模式)

【问题讨论】:

  • 是的,Java 正在回收内部字符串。
  • this answer
  • 谢谢!我刚刚看到“10056 个实习字符串,占用 847280 个字节”。

标签: java garbage-collection


【解决方案1】:

是的,内部字符串被回收。正如Java SE 7 Features and Enhancements 中所述,建议:

在 JDK 7 中,interned 字符串不再分配在永久 Java 堆的生成,而是分配在主堆中 Java 堆的一部分(称为年轻代和年老代),沿 与应用程序创建的其他对象。这一变化将 导致更多的数据驻留在主 Java 堆中,而更少的数据在 永久代,因此可能需要堆大小为 调整。大多数应用程序只会看到相对较小的差异 由于此更改,堆使用量增加,但加载的应用程序更大 许多类或大量使用 String.intern() 方法将看到 更显着的差异。

【讨论】:

  • 我在 Marko 的评论中提到的帖子中使用 Eclipse 20121004-1855 中的 Java 6 测试了 the code;好吧,同样的行为。不过,我机器上安装的 JRE 是 7。 java 版本 "1.7.0_09" Java(TM) SE Runtime Environment (build 1.7.0_09-b05) Java HotSpot(TM) 64-Bit Server VM (build 23.5-b02, mixed mode)
  • @user2081147:是的,我在寻找针对实习字符串的相同 gc 内容时也浏览了该代码。它表明实习字符串确实是 GCed,因为我们为相同的实习字符串获得了不同的哈希码。此外,在此链接oracle.com/technetwork/java/javase/… 中还可以看到一件事,Permgen 还包含虚拟内存。所以当 Permgen 增加其最大限制时,它会被 gced。这种情况取决于 java6 。现在实习字符串没有存储在 permgen 中,它们仍然是垃圾收集,正如这段代码所证明的那样。
  • 哇,@Vishal,很棒的收获!我从来没有注意到右边的小灰紫色区域。
  • 太小而无法注意到 ;)
猜你喜欢
  • 1970-01-01
  • 2011-03-27
  • 1970-01-01
  • 2011-04-22
  • 2011-10-02
  • 1970-01-01
  • 2012-05-21
  • 2017-12-23
  • 2013-04-01
相关资源
最近更新 更多