我相信这个垃圾是在应用程序的各个地方调用new String时创建的。如何在不每次创建新对象的情况下"创建"字符串?
之所以成为这种垃圾敏感的原因是因为我的应用程序不能创建垃圾,因为我们需要用默认的Java GC实时运行。
// you can see I use the same chars array
public String getB37String() {
long l = getLong();
int i = 0;
while (l != 0L) {
long l1 = l;
l /= 37L;
chars[11 - i++] = validChars[(int) (l1 - l * 37L)];
}
return new String(chars, 12 - i, i);
}
例如,使用StringBuilder.toString(),下面使用new String。
// and you can see that I use the same builder
public String getString() {
builder.delete(0, builder.length());
char ascii;
while (0 != (ascii = (char) getUByte()) && backing.hasRemaining())
builder.append(ascii);
return builder.toString();
}
号
如果你需要使用相同的字符串内容,例如"Java",如果你使用String ="Java",第一次它将创建一个新的对象,之后,没有新的对象被创建,它们是从字符串池中提取的。如果每次创建新对象时都使用new,不管它是否已存在于池中,因此无论哪种方式,每次分配新内存时都将始终创建新的字符串内容
我仍然不清楚你问题背后的动力是什么。您是否遇到性能问题?您的标题表明您可能有太多的char数组。如何避免创建新的字符串来帮助您?这似乎是一个臭名昭著的谬论问题。你能澄清一下吗?
@sstan这些char数组是支持许多字符串的数组。我的应用程序中需要零垃圾,使用new String和StringBuilder.toString都会产生垃圾。我想知道是否有任何技巧可以在文本池中创建字符串(或者其他一些防止垃圾的解决方案)!
@吉尔:我的观点是,即使你能做到这一点,你目前正在传递给String构造函数的char数组,或者支持StringBuilder的char数组又如何呢?那些垃圾也不是吗?但不管你在做什么,你不需要这些吗?您真的确定避免创建这个String实例会真正解决您的问题吗?
@sstan如果您注意到这些方法没有生成新的char数组或StringBuilder,而是重用这些对象。姜饼头下面似乎有解决办法!
@吉尔:因为我不认为intern()的想法会对你想要实现的目标起作用,所以我认为关键是理解你的方法getB37String()和getString()是如何被调用和使用的。是否确实需要返回字符串?你能改为播放流媒体吗?否则,我看不到如何避免创建在某个时刻需要收集的对象。您是否会从寻找调优GC如何执行集合的方法中获益更多?(多久、多久等…)
@Jire,"在文本池中创建字符串"不会神奇地阻止垃圾。它仍然需要被创建。当它不再使用时,它仍然会被垃圾收集。字串文字不神奇