Java 如何从字符串池中删除未传递的值?

Java 如何从字符串池中删除未传递的值?,java,Java,我很好奇字符串池中的值是如何被删除的 假设: String a = "ABC"; // has a reference of string-pool String b = new String("ABC"); // has a heap reference b = null; a = null; 对于GC,会收集堆中的“ABC”,但“ABC”仍在池中(因为它在permGen和GC中不会影响它) 如果我们继续添加值,如: String c = "ABC"; // pointing to 'AB

我很好奇字符串池中的值是如何被删除的

假设:

String a = "ABC"; // has a reference of string-pool
String b = new String("ABC"); // has a heap reference

b = null;
a = null;
对于GC,会收集堆中的“ABC”,但“ABC”仍在池中(因为它在permGen和GC中不会影响它)

如果我们继续添加值,如:

String c = "ABC"; // pointing to 'ABC' in the pool. 

for(int i=0; i< 10000; i++) {
  c = ""+i;
  // each iteration adds a new value in the pool. Previous values don't have a pointer.
}
String c=“ABC”//指向池中的“ABC”。
对于(int i=0;i<10000;i++){
c=”“+i;
//每次迭代都会在池中添加一个新值。以前的值没有指针。
}
我想知道的是:

  • 池是否会删除未引用的值?如果不是,则表示池正在消耗不必要的内存
  • 那么,JVM正在使用这个池,这有什么意义呢
  • 什么时候会出现性能风险
作为本规范的一部分

String c = "ABC"; // pointing to 'ABC' in pool. 

for(int i=0; i< 10000; i++) {
  c = ""+i; // each iteration add new value in pool. and pervious values has no pointer  

}
String c=“ABC”//指向池中的“ABC”。
对于(int i=0;i<10000;i++){
c=”“+i;//每次迭代都会在池中添加新的值。以前的值没有指针
}
池中只有两个
String
对象,这两个对象来自两个
String
文本、
“ABC”
。从连接中创建的每一个
字符串
都将是具有常规GC行为的常规对象,即当它们不再可访问时,收集的候选对象

来自池中
String
文本的
String
值将不会被收集,因为它们总是可以访问的(使用类加载器的YMMV)<代码>字符串插入但不来自文本的对象应该以常规方式成为GC的候选对象

更多阅读内容:


我怀疑只有
“ABC”和
(第二个示例)是永久的,但我不是专家。
c
不在池中,字符串是不可变的。每次连接时都会创建一个新字符串,而这些字符串不在池中。这看起来像一个优化(“ABC”+“D”)。我建议在两个循环中创建字符串,然后比较它们。这更难优化:-)@MuneebNasir
c
最初引用池中的字符串,然后不引用。您的示例很差,因为Java将在编译过程中连接。仅供参考,JDK 8和上面的版本不再有
PermGen
。我知道我的示例代码很差。你提供的任何链接都是有用的。谢谢