9

我正在开发一个有很多重复字符串的应用程序,我的任务是消除它们以减少内存使用。我的第一个想法是用来String.intern保证一个 String 的引用只会存在。它可以减少堆内存,但它增加了 PermGen 太多了;事实上,因为有很多字符串只声明一次,应用程序使用的内存总量实际上增加了。

在寻找其他想法后,我发现了这种方法:https ://stackoverflow.com/a/725822/1384913 。

它发生了与 String.intern 相同的事情:String 使用量减少了,但我保存的内存正在用于WeakHashMapWeakHashMap$Entry类中。

有没有一种有效的方法来为每个不花费与我正在恢复的内存量相同的内存量的字符串维护一个引用?

4

3 回答 3

1

我找到了一个替代方案WeakHashMapWeakHashSetEclipse JDT 库提供的。它具有与 相同的行为WeakHashMap,但它使用的内存更少。此外,您只需要调用该方法add,如果它尚不存在,它将在集合中添加字符串,否则返回现有的。

我唯一不喜欢的是它不使用泛型,这迫使开发人员强制转换对象。我的intern方法非常简单,如下所示:

声明WeakHashSet

private static WeakHashSet stringPool = new WeakHashSet(30000); //30 thousand is the average number of Strings that the application keeps.

和实习生方法:

public static String intern(String value) {
    if(value == null) {
        return null;
    }
    return (String) stringPool.add(value);
}
于 2012-10-16T17:07:40.703 回答
0

为什么不使用 StringBuilder/StringBuffer 类而不是 String。使用此类的实例,您始终可以使用具有不同值的相同实例。- 安库尔

于 2012-10-16T09:40:57.817 回答
0

在类似的情况下,我尽可能将字符串常量重构为枚举。这样,您将获得两个好处:

  • 枚举实例是单例,所以你不会有内存问题
  • 使用字符串时没有拼写错误。

缺点:

  • 大量的工作,如果你没有足够的测试用例,犯错的可能性是无限
  • 有时这不是微不足道的,例如当您必须与第三方库交互时,您不能只编辑......
  • 如果这些是运行时确定的,而不是编译时间,那简直是不行...
于 2012-10-16T09:57:11.487 回答