0

i know "a" and new String("b") both will create "a"or "b" in constant pool

But why the following program doesn't throw outOfMemoryError?

Does new String("b") create nothing in constant pool?

List<String> s = new ArrayList<String>();
// -XX:PermSize=5M
// -XX:MaxPermSize=5M
// why no oom:pergen space throw???? "i" isn't in constant pool????
for (;;) {
    for (int i = 0; i < 1000000; i++) {
        s.add(new String("" + i));
    }
}
Yassin Hajaj
  • 21,337
  • 9
  • 51
  • 89
superman
  • 51
  • 6
  • 1
    No, `new String("b")` creates string in heap – singhakash Dec 25 '15 at 11:59
  • [please have a look](http://stackoverflow.com/questions/34440594/a-vs-new-stringa-vs-new-stringa-intern-in-string-constant-pool). @singhakash the both creates string in constant pool ,but new String("b") also create String Object in heap. – superman Dec 25 '15 at 12:12
  • 1
    Possible duplicate of [What is the difference between "text" and new String("text")?](http://stackoverflow.com/questions/3052442/what-is-the-difference-between-text-and-new-stringtext) – Tarik Dec 25 '15 at 12:14
  • 1
    This creates 1,000,000 String objects, each having at most 6 characters, so 12 bytes. Let's add 20 bytes overhead per String object, that makes 32,000,000 bytes, i.e. 32 MBs of memory. This is probably much less memory than the heap size of your JVM has. – JB Nizet Dec 25 '15 at 12:57

2 Answers2

4

new String(...) is creating object in normal heap, so limiting permanent generation won't fire off OOME. With older version of java you could simulate it by calling .intern() on resulting string, but even that has changed recently (please read http://java-performance.info/string-intern-in-java-6-7-8/ for details).

In java 8, perm generation seems to be completely gone http://www.infoq.com/articles/Java-PERMGEN-Removed so unless you specifically target older versions, it might be counterproductive trying to find its limits and instead try to understand Metaspace.

Artur Biesiadowski
  • 3,595
  • 2
  • 13
  • 18
1

I know "a" and new String("b") both will create "a"or "b" in constant pool

Your "knowledge" is incorrect:

  1. You are actually talking about the string pool here. (The constant pool is part of the class file format, and things are "created" there by the compiler, etc.)

  2. While "a" and "b" will be placed in the string pool, the expression new String("b") does not create (or reuse) a string in the string pool. It creates a new String object in the regular heap.

Point 2 explains why you can't fill permgen (on a JVM where it exists) by simply creating strings using new String(...).

If you want to force strings into the string pool, you need to use String.intern. If you modified your code to the following, you should be able to trigger an OOME in the permgen heap (Java 7 and earlier):

for (;;) {
    for (int i = 0; i < 1000000; i++) {
        s.add((new String("" + i)).intern());
    }
}
Stephen C
  • 698,415
  • 94
  • 811
  • 1,216