通过子字符串解析后如何回收内存?intern() 还是 new String()?
简短版本:如果调用 string.substring(n,m).intern(),字符串表是保留子字符串还是原始字符串?
...但我不确定这是正确的问题,所以这是长版本:
我正在使用传统的Java代码(PCGen),它通过将每个文件作为一个大字符串进行诽谤来解析文件,然后使用String.split,.trim,.substring和StringTokenizer将它们分解为标记。这对于解析非常有效,因为这些方法都没有复制原始字符串,而是都指向共享char[]的各个部分。
解析结束后,我想回收一些内存。只需要原始大字符串的几个小子字符串,但强引用可防止收集大字符串。后来我遭受了OOM,我相信部分原因是许多解析文件的巨大堆影响。
我知道我可以通过(写入时复制)修剪大字符串。我知道我可以通过String.intern减少字符串重复(这很重要,因为解析的文件中有很多冗余)。我需要同时使用两者来回收最大数量的堆,还是 .intern() 同时使用这两者?阅读OpenJDK7热点源代码(hotspot/src/share/vm/classfile/symbolTable.cpp),看起来字符串表保留了整个字符串,并且根本不会修剪它的偏移量/长度。所以我认为我需要做一个新的字符串,然后进一步研究这个结果。右?new String(String)
总而言之,切换到流式解析器在内存方面将是一个巨大的胜利,但这在短期内是一个太大的变化。