2

我已经阅读了关于 SO 的问题,解释 Java 自动实习字符串文字,并且显然在intern()被调用时实习。但是,我想知道是否在一个循环(foreach在我的情况下是一个循环)中,字符串也会自动被实习。我问是因为我正在实习字符串以节省几个非常大的内存,LinkedHashMaps并且想知道调用intern()是否是多余的。

例子:

String array[] = createLargeArbitraryArray();
Map<String, Float> map = new LinkedHashMap<String, Float>(array.length);
for (String s : array)
  map.put(s, 1f);
}

下一个示例是否会在内存使用方面与第一个示例(假设相同的array值)有任何差异,或者s此时已经被实习了?

String array[] = createLargeArbitraryArray();
Map<String, Float> map = new LinkedHashMap<String, Float>(array.length);
for (String s : array)
  map.put(s.intern(), 1f);
}

我意识到在这种情况下,可能没有等效的字符串,但在我的情况下,我有几个地图的自定义键,最终确实使用了重复的字符串值,我想知道调用intern()以节省内存是否是多余的在此刻。

为了补充这个问题,如果一个数组是从文字创建的(在这种情况下,它们最初是实习的),然后作为参数传递给一个方法,上面的循环是否会使用实习字符串?IE:

/**
 * @param array created from literals
 */
public void populateMap(String[] array) {
  for (String s : array)
    map.put(s, 1f); // Interned or not?
}

在这种情况下,要么s是因为array一开始就被实习而被实习,要么因为s在循环参数中被声明为新对象而未被实习。哪个是对的?

编辑:为了进一步解释我实习的原因,我想释放堆中的内存以避免达到最大堆大小或 GC 开销限制。在这种情况下,性能和速度对我来说并不是非常重要。

4

1 回答 1

2

在这里明确调用intern()是正确的方法(或者像 PC luddite 所说,检查你是否真的需要实习)。我不知道 JVM 中有任何 JIT 编译器可以做到这一点(即使有一些优化可以做到这一点,你也不应该依赖它)。

如果一个数组是从内部字符串创建的,然后传递给一个方法然后使用,那么将使用“内部”字符串。不会创建其他字符串。

于 2016-08-09T15:12:49.113 回答