2008-09-16 6 views
4

Массив ints в java хранится как блок из 32-битных значений в памяти. Как хранится массив объектов Integer? т.е.Как массивы Integer хранятся внутри, в JVM?

int[] vs. Integer[] 

Я бы себе, что каждый элемент массива Integer является ссылкой на объект Integer, и что объект Integer имеет объект хранения накладные расходы, так же как и любой другой объект.

Я надеюсь, однако, что JVM совершает магические умения под капотом, учитывая, что целые числа неизменяемы и сохраняют его точно так же, как массив ints.

Является ли моя надежда ужасно наивной? Является ли массив Integer намного медленнее, чем массив int в приложении, где важна каждая последняя унция производительности?

ответ

11

Нет VM Я знаю будет хранить Integer [] массив как в INT [] массив по следующим причинам:

  1. Там может быть нулевых объектов Integer в массиве, и у вас есть биты не остались для указания этого в массиве int.Тем не менее, VM может хранить эту 1-битную информацию на каждый сегмент массива в hiden bit-array.
  2. Вы можете синхронизировать элементы массива Integer. Это намного сложнее преодолеть в качестве первой точки, так как вам нужно будет сохранить объект монитора для каждого слота массива.
  3. Элементы Integer [] можно сравнить для идентификации. Например, вы можете создать два объекта Integer со значением 1 через новый и сохранить их в разных слотах массива, а позже вы их получите и сравните с помощью ==. Это должно привести к ошибке, поэтому вам нужно будет хранить эту информацию где-нибудь. Или вы сохраняете ссылку на один из объектов Integer где-то и используете это для сравнения, и вы должны убедиться, что одно из сравнений == - false и одно true. Это означает, что вся концепция идентичности объекта является тихой, трудно обрабатываемой для оптимизированного массива Integer.
  4. Можно указать целое число [], например. Object [] и передать его методам, ожидающим только Object []. Это означает, что весь код, который обрабатывает Object [], теперь должен иметь возможность обрабатывать специальный объект Integer [], делая его медленнее и больше.

Принимая все это во внимание, вероятно, было бы возможно сделать специальный Integer [], который экономит место в сравнении с наивным реализации, но дополнительная сложность, скорее всего, повлияет много другого кода, что делает его медленнее в конце.

Накладные расходы, связанные с использованием Integer [] вместо int [], могут быть тихими большими в пространстве и времени. На типичной 32-битной виртуальной машине объект Integer будет потреблять 16 байт (8 байт для заголовка объекта, 4 для полезной нагрузки и 4 дополнительных байта для выравнивания), в то время как Integer [] использует столько же места, сколько int []. В 64-битных виртуальных машинах (с использованием 64-битных указателей, что не всегда так) объект Integer будет потреблять 24 байт (16 для заголовка, 4 для полезной нагрузки и 4 для выравнивания). Кроме того, слот в Integer [] будет использовать 8 байт вместо 4, как в int []. Это означает, что вы можете ожидать накладные расходы 16 до 28 байт на каждый слот, что составляет фактор от 4 до 7 по сравнению с обычными массивами int.

Накладные производительность может быть значительным тоже по двум основным причинам:

  1. Поскольку вы используете больше памяти, вы положили на гораздо большее давление на подсистемы памяти, что делает его более вероятно, будет иметь кэш-промахов в случае от Integer []. Например, если вы перемещаете содержимое int [] линейным образом, кэш будет иметь большинство записей, которые уже были извлечены, когда они вам понадобятся (так как макет также линейный). Но в случае массива Integer объекты Integer могут быть разбросаны случайным образом в куче, что затрудняет предсказание кэша, где будет указываться следующая ссылка на память.
  2. Сбор мусора должен выполнять гораздо больше работы из-за использования дополнительной памяти и потому, что он должен сканировать и перемещать каждый объект Integer отдельно, в то время как в случае int [] это всего лишь один объект и содержимое объекта не нужно сканировать (они не содержат ссылок на другие объекты).

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

1

Я думаю, что ваша надежда ужасно наивная. В частности, ему нужно решить проблему, что Integer может быть пустым, тогда как int не может быть. Только это достаточно для хранения указателя на объект.

Таким образом, фактический указатель объекта будет иметь неизменяемый экземпляр int, особенно для выделенного подмножества целых чисел.

0

Это не будет намного медленнее, но поскольку Integer [] должен принимать «null» как запись, а int [] не требуется, будет задействован некоторый объем учета, даже если Integer [] подкрепляется int [].

Так что, если каждый последний унция вопросов производительности, пользователь INT []

0

Причина, по которой Integer может быть нулевым, в то время как INT не может, потому, что Integer является полноценным объектом Java, со всеми накладными расходами, что включает. Там это значение в этом, так как вы можете написать

Integer foo = new Integer(); 
foo = null; 

, который хорошо говорил, что Foo будет иметь значение, но это еще не.

Другое отличие состоит в том, что int не выполняет вычисления переполнения. Например,

int bar = Integer.MAX_VALUE; 
bar++; 

будет весело увеличиваем бар, и вы в конечном итоге с очень отрицательным числом, которое, вероятно, не то, что вы хотели в первую очередь.

foo = Integer.MAX_VALUE; 
foo++; 

будет жаловаться, что, я думаю, будет лучшим поведением.

Последний вопрос заключается в том, что Integer, являющийся объектом Java, несет в себе пространственные служебные данные объекта. Я думаю, что кому-то может понадобиться перезвонить здесь, но я считаю, что каждый объект потребляет 12 байт для служебных данных, а затем пространство для самого хранилища данных. Если вы после производительности и пространства, я задаюсь вопросом, является ли Integer правильным решением.

 Смежные вопросы

  • Нет связанных вопросов^_^