Java String.intern() 方法

是什么? 为什么?

看到有个统计说, 在 JVM 的内存中, String 大概占到20% ~ 50% 的内存区, 那么这么多的 String 必定有很多重复的, 既然是重复的, 那就可以只在内存放一份, 所有使用这个 String 的 reference 都指向同一块内存. 那么 JVM 就在 permanet generation 放置了一个 StringSet(也有称 StringTable, StringCache), 当一个 String instance 调用 intern 方法的时候, 它先检查这个 String 在 StringSet 中是否存在, 如存在, 就返回这个存在的 String, 否则, 在 StringSet 中添加这个 String, 并且返回新加的这个 String.
这前提是基于: Java 的 String 是 immutable 的: 如果你改变了 String 的一部分, 原来的 reference 就指向了一个新的String. 如果都在原来的 String 的内存区修改, 那么就不能放到 StringSet 了.
另外, 编译器自动把你程序中的类名, 方法名, String 常量值, 字面值 等都事先放入了 StringSet. 这个 StringSet 是有 String 这个 class 所管理的.
类似的机制, 在整数类型 (Byte, Short, Integer, Long) 的 valueOf 方法中都有体现, 默认 -128 ~ 127 都放入了 cache.

优缺点?

如果你有大量的重复的 String 值要在程序中使用, 并且是运行时生成的 String, 通过 intern 方法, 会大大节省内存, 并且减少 GC 的量. 但是, 带来是效果是需要能多的时间. 时间 VS 内存. 关于时间和内存的比较, 详细可以看 refer 2.

如果是仅仅使用 intern 的值来用 == 对比, 完全没有必要, 时间上算起来, 差不多.


摘抄:
String interning takes a String instance (so it already exists in the Heap) and checks if an identical copy exists already in a StringTable.
That StringTable is basically a HashSet that stores the String in the Permanent Generation. The only purpose of that Table is to keep a single instance of the String alive. If it is in there, the instance is returned. If its not, its added to the String Table
Note that ALL Strings which are hardcoded (as constant or anywhere in code) are automatically interned by the compiler.

参考:

  1. Save Memory by Using String Intern in Java
  2. String spec

标签: none

添加新评论