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 callintern()
?
Asked
Active
Viewed 171 times
3

voismager
- 433
- 4
- 19
-
the pool is *still* in the heap, and that long-lived objects will get GC-ed. – Eugene Jul 31 '18 at 13:36
-
3`Console`'s `readPassword()` methods return a `char[]` for this reason. So, "don't create a `String` in the first place" I'd say. – daniu Jul 31 '18 at 13:38
-
@daniu yeah actually that is the reason why I asked this question :) – voismager Jul 31 '18 at 13:46
1 Answers
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
-
1If 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
-
1One 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