/ / “A” срещу “new String (“ b ”)” в Constant Pool (JVM JDK 6) (желание за истината) - java, string, изключение, jvm

"" Срещу "нов стринг (" b ")" в константен басейн (JVM JDK 6) (нетърпелив за истината) - java, string, exception, jvm

Знам "a" и new String("b") и двете ще създадат "a"или "b" в постоянен басейн

Но защо следната програма не хвърля outOfMemoryError?

Прави new String("b") не създавате нищо в постоянен басейн?

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));
}
}

Отговори:

4 за отговор № 1

нов низ (...) създава обект в нормална грамада, така че ограничаването на постоянно поколение няма да запали OOME. С по-стара версия на Java можете да симулирате, като се обадите на .intern () на получения низ, но дори това се е променило наскоро (моля, прочетете http://java-performance.info/string-intern-in-java-6-7-8/ за детайли).

В java 8 изглежда, че перм поколението изглежда напълно изчезнало http://www.infoq.com/articles/Java-PERMGEN-Removed така че, освен ако не се насочите конкретно към по-старите версии, може да се окаже контрапродуктивно да се опитате да намерите своите граници и вместо това да се опитате да разберете Metaspace.


1 за отговор № 2

Знам "a" и new String("b") и двете ще създадат "a"или "b" в постоянен басейн

Вашето "знание" е неправилно:

  1. Всъщност говорите за струнния пул тук. (Постоянният пул е част от формата на файловете на класа и там нещата се „създават“ от компилатора и т.н.)

  2. Докато "a" и "b" ще бъде поставен в низовия пул, изразът new String("b") не създава (или използва повторно) низ в пула с низове. Той създава нов String обект в обичайната грамада.

Точка 2 обяснява защо не можете да запълвате permgen (на JVM, където съществува), като просто създавате низове, като използвате new String(...).

Ако искате да форсирате струни в низбасейн, трябва да използвате String.intern. Ако сте променили кода си на следното, трябва да можете да задействате OOME в купчината на permgen (Java 7 и по-стари):

for (;;) {
for (int i = 0; i < 1000000; i++) {
s.add((new String("" + i)).intern());
}
}