Это Sun JDK 1.6u21, x64.
У меня есть класс для экспериментов с использованием разрешений, который содержит только одну большую строку (512 тыс. Символов):
public class Big0 {
public String bigString =
"A string with 2^19 characters, should be 1 MB in size";
}
Я проверяю использование perm gen с помощью getUsage().toString()
для объекта MemoryPoolMXBean
для постоянного поколения (называемого «PS Perm Gen» в u21, хотя у него немного разные имена с разными версиями или с разными сборщиками мусора.
Когда я впервые обращаюсь к классу, скажем, читая Big0.class
, perm gen скачет на ~ 500 КБ - это то, что я ожидаю, так как кодировка строки в постоянном пуле - UTF-8, и я используютолько символы ASCII.
Однако, когда я на самом деле создаю экземпляр этого класса, perm gen увеличивается на ~ 2 МБ. Поскольку это 1 МБ строки в памяти (2 байта на символ UTF16, конечно, никаких суррогатов)), Я запутался, почему использование памяти удваивается.
Тот же эффект возникает, если я делаю строку статической. Если я использовал final, он не компилируется, так как я превышаю предел для coэлементы постоянного пула размером 65535 байт (не уверен, почему этого не следует делать и при окончательном отключении - считайте, что это бонусный вопрос).
Любое понимание приветствуется!
Редактировать: Я долженТакже отметим, что это происходит с нестатическими, конечными нестатическими и статическими строками, но не с окончательными статическими строками.Поскольку для строковых констант это уже лучшая практика, возможно, это в основном представляет академический интерес.