Требуется ли пространство памяти для константы статической строки в Java? - PullRequest
2 голосов
/ 29 октября 2010

Сколько памяти выделит JVM для 1) Статической строки 2) Статического целого числа

Я исследую эту проблему, поскольку получаю исключение кучи памяти из памяти, в моем приложении 8 файлов констант и каждаяВ файле почти 300 статических констант.

Является ли хорошей практикой объявление всех констант в качестве статических или какой-либо другой практики, которой я могу следовать?

Ответы [ 5 ]

4 голосов
/ 29 октября 2010

Сколько памяти выделит JVM для 1) Статической строки 2) Статического целого числа

(Чтобы упростить ситуацию, я предполагаю, что речь идет о 32-битной JVM. Также обратите внимание, чтоэти числа приблизительные и специфичные для JVM .)

Простая первая - каждая статическая переменная Integer занимает 4 байта памяти для ссылки плюс 4 байта+ 1 заголовок объекта (обычно 8 байтов IIRC).Итого - 16 байтов.

(И если вы говорите о статических int переменных, то это всего 4 байта на int.)

Статическая переменная String представляет собойнемного сложнее ... и дороже:

  • Статическая ссылочная переменная составляет 4 байта.
  • Объект String имеет 4 поля по 4 байта + заголовок объекта 1 x 2 слова: это 24 байта.
  • Одно из этих полей относится к массиву char, который имеет заголовок из 3 слов итребует (string.length() + 3) / 4 байтов для содержимого - это 12 + несколько кратных 4 байтам.
  • Если значение String является константой времени компиляции, то строка будет интернирована, и это добавит несколько дополнительных байтов длязапись хеш-таблицы пула строк.(32 байта было бы разумным предположением.)

Добавьте все это, и вы получите (скажем) 80+ байтов на строку, в зависимости от длины строки.Но почти все эти байты являются представлением самой (интернированной) строки.Только 4 байта из-за использования static.

Я исследую эту проблему, так как получаю исключение кучи памяти из памяти, в моем приложении 8 файлов констант и каждый файлимеет почти 300 статических констант.

Это незначительно.OOME почти наверняка вызвано чем-то другим.

Является ли хорошей практикой объявление всех констант как статических или любой другой практики, которой я могу следовать?

ЭтоРекомендуется объявлять реальные константы статическими, вплоть до некоторой точки.

Однако большое количество констант в исходном коде становится громоздким, и в конечном итоге вы сталкиваетесь с ошибками компиляции из-за ограничений в формате байт-кодафайл.В этот момент (и, вероятно, задолго до этого) вы должны переместить константы из вашего исходного кода в базу данных или файл конфигурации.

Скорее всего, вы столкнетесь с ограничением в формате байт-кода задолго до памятииспользование становится серьезной проблемой.

3 голосов
/ 29 октября 2010

2400 Строковые константы не выгонят вас из памяти. При щедрой 10K каждый, это будет всего 24MB. При более обычной скорости в 100 байт каждый это всего лишь 240K.

Я бы искал боров памяти где-то еще.

2 голосов
/ 29 октября 2010

Сколько места занимает строковый объект, конечно же, зависит от длины строки.

Помимо символов самой строки, строка содержит несколько полей управления, но я считаю их 28 байтами плюс еще один встроенный объект (ObjectStreamField), я не уверен, насколько он велик, но в любом случае это может быть несколько дюжина байтов. Каждый символ занимает 2 байта. Вам нужно, я думаю, 8 байт для ручки. Если у вас есть строки, что, может быть, 20 символов или около того каждый?, Может быть, у вас есть до 100 байтов на строку. Так, как говорит Тило, 2400 строк могут звучать как много, но это займет сотни кБ. Если вы не говорите о Java, встроенной в наручные часы, или о какой-то столь жесткой среде, трудно себе представить, что это станет значительным фактором потери вашей памяти.

1 голос
/ 29 октября 2010

Я предполагаю, что оба являются статическими и final, так как вы называете их константами.

Если примитивный тип или строка определены как константа, а значение известно во время компиляции, компилятор заменяет имя константы везде в коде на ее значение. Это называется константа времени компиляции . Для примитивных типов нет необходимости использовать кучи памяти. Строки интернированы, и только одна копия должна храниться в куче.

В любом случае, я не верю, что строки 8 x 300 вызывают нехватку памяти. Ваша проблема должна быть где-то еще.

0 голосов
/ 29 октября 2010

Насколько велики ваши постоянные строки?

Память, используемая строками, имеет порядок 8 * 300 * 2 * средняя длина = ~ 5k * средняя длина. Кажется, недостаточно использовать всю вашу память.

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

public static final String A_STRING = "this String is constant"; 

Обратите внимание, что это ссылка, которая устанавливается постоянной модификатором 'final', а не сам объект.

...