Сохраняет ли CLR / JVM один пул для всех работающих приложений .net / java? - PullRequest
6 голосов
/ 04 июля 2011

Ниже приводится выдержка из MSDN:

Общеязыковая среда выполнения сохраняет строковое хранилище, поддерживая таблицу, называемую внутренним пулом, которая содержит одну ссылку на каждыйуникальная литеральная строка, объявленная или созданная программно в вашей программе.Следовательно, экземпляр литеральной строки с определенным значением существует только один раз в системе.

Например, если вы назначаете одну и ту же строку литерала нескольким переменным, среда выполнения получает одну и ту же ссылку на строку литерала извнутренний пул и назначает его каждой переменной.

Метод Intern использует внутренний пул для поиска строки, равной значению str.Если такая строка существует, возвращается ее ссылка в пуле интерна.Если строка не существует, ссылка на str добавляется во внутренний пул, затем эта ссылка возвращается..... Если вы пытаетесь уменьшить общий объем памяти, выделяемой вашим приложением, имейте в виду, что интернирование строки имеет два нежелательных побочных эффекта.Во-первых, память, выделенная для интернированных объектов String, вряд ли будет освобождена до тех пор, пока не закончится среда CLR.

Значит ли это, что CLR сохраняет один единственный внутренний пул для всехзапуск приложений .net?Пример: если программа A создает строковый литерал «Test» и если другая программа пытается создать другой строковый литерал «Test», используется та же копия?Тот же вопрос относится и к JVM.

Ответы [ 4 ]

2 голосов
/ 04 июля 2011

CLR поддерживает внутренний пул для каждого экземпляра. Если вы читаете дальше по ссылке MSDN :

Если вы пытаетесь уменьшить общий объем памяти, выделяемой вашим приложением, имейте в виду, что интернирование строки имеет два нежелательных побочных эффекта. Во-первых, память, выделенная для интернированных объектов String, вряд ли будет освобождена до тех пор, пока не закончится среда CLR.

Для Java вы также запускаете JVM.

Однако согласно этой статье :

Этот миф идет в противоположном направлении к мифу 2. Некоторые люди верят, что усвоенные строки остаются в памяти, пока не закончится JVM. Возможно, это было правдой давно, но сегодня интернализованные строки являются сборщиком мусора, если на них больше нет ссылок. Смотрите ниже слегка измененную версию программы выше. Время от времени очищает ссылки на интернализованные строки. Если вы проследите за выполнением программы из jconsole, вы увидите, что использование пространства PermGen увеличивается и уменьшается, так как сборщик мусора освобождает память, используемую внутренними строками без ссылок.

Что означает, что в Java встроенные строки могут на самом деле получить GCed.

1 голос
/ 04 июля 2011

Нет, потому что не может.
Каждое приложение работает в своем собственном пространстве виртуальной памяти.Вы не можете совместно использовать данные между двумя областями памяти.
И рассмотрите последовательность загрузки / выгрузки.Это станет очень сложным, и вы никогда не сможете удалить строку.
Также обратите внимание на эту часть вашей цитаты:

каждая уникальная литеральная строка, объявленная или созданная программно в вашей программе.


ОК, просто прочитав немного дальше на этой странице MSDN:

ссылка CLR на интернированный объект String может сохраняться после вашего приложения или даже вашего домена приложения., заканчивается.

0 голосов
/ 24 марта 2013

Как я понимаю, для CLR это один на время выполнения, а не на домен приложения. Из Джеффри Рихтера "CLR Via C #"

Обратите внимание, что сборщик мусора не может освободить строки, на которые ссылается внутренняя хеш-таблица, потому что хеш-таблица содержит ссылку на эти объекты String. Строковые объекты, на которые ссылается внутренняя хеш-таблица, не могут быть освобождены до тех пор, пока домен приложения не будет выгружен или процесс не завершится.

Это говорит о том, что таблица отделена от AppDomain.

JVM не имеет этой концепции, поэтому нет двусмысленности. У вас могут быть разные загрузчики классов, но трудно представить, что у вас будут разные загрузчики классов для String.

0 голосов
/ 04 июля 2011

Что касается Java, то да. Строковые литералы хранятся в пуле на JVM. Выдержка из JavaDoc String#intern(): All literal strings and string-valued constant expressions are interned. String literals are defined in §3.10.5 of the Java Language Specification

...