3
  • Is there a legal way to force JVM not to store particular String instance in a long-lived string pool?

  • Does new String() provide this feature and I can be 100% sure that value created this way will be put into the heap and not into the pool unless I call intern()?

voismager
  • 433
  • 4
  • 19

1 Answers1

3

Is there a legal way to force JVM not to store particular String instance in a long-lived string pool?

Other than not initializing it with a string literal, I'm afraid there isn't.

Does new String() provide this feature and I can be 100% sure that value created this way will be put into the heap and not into the pool unless I call intern()?

Yes (keep in mind that if you write String str1 = new String("Hello");, then the String instance referred to by str1 will not get internalized, while the String instance created for the literal string "Hello" will).

Also note that where exactly the pool gets stored in the heap depends on the version of the JVM as explained here

crizzis
  • 9,978
  • 2
  • 28
  • 47
  • "while the `String` instance created for the literal string `"Hello"` will". Guess I should stick to raw `char[]` then. – voismager Jul 31 '18 at 13:54
  • 1
    If security is your concern, you should definitely use `char[]`, since it can be explicitly erased (by overwriting its contents). Even if the `String` does not end up in the string pool, there's no guarantee as to when the GC will collect it (and even then, until the memory gets reused by some other object, the raw bytes persist) – crizzis Jul 31 '18 at 13:59
  • 2
    @crizzis using `char[]` is just pretending a higher security which isn’t there. In a garbage collected heap, there can be an arbitrary number of copies flying around and you’re overwriting just one of them. Further, overwriting an array as the last action on it, may get optimized away by the JVM. – Holger Jul 31 '18 at 14:06
  • @Holger Perhaps I oversimplified my point. [Here](https://stackoverflow.com/questions/8881291/why-is-char-preferred-over-string-for-passwords) is a more detailed discussion on the subject – crizzis Jul 31 '18 at 14:10
  • @crizzis well, that’s quite a complicated topic, but it’s entirely unrelated to the OP’s concerns about the *pool*. If the pool has a reference to a string instance, it still will get garbage collected, if there is no other reference to it. But if there is a reference to it, not being in the pool wouldn’t make a difference. And if you construct a new `String` instance, it is never in the pool. But if you suspect, someone *could* call `intern()` on it, don’t forget that the same guy could call `new String(yourCharArray).intern()`. So it makes no difference *regarding the pool*. – Holger Jul 31 '18 at 14:14
  • 1
    One option is to use a direct ByteBuffer for security information e.g. private keys. This will only be at one location in memory and can be overwritten when not used. – Peter Lawrey Aug 01 '18 at 14:50