Pull to refresh

Comments 43

Какая будет разница по потреблению памяти между конструкциями `new int[1024]` и `new Integer[1024]`?
Сильно зависит от платформы, версии Java и ключей JVM.
Если int[1024] всегда занимает около 4K, то объем Integer[1024] может варьироваться от тех же 4K
(при -XX:+UseCompressedOops -XX:+AggressiveOpts) до 28K (при -XX:-UseCompressedOops).
В данном случае все тестирование происходило без всяких ключей и на Java 1.6
И да. Исходники именно для того присутствуют, чтобы вы могли на своей конфигурации(архитектура/версия жавы/ключи) запустить и посмотреть.
Спасибо. Для меня очень полезная информация.
Вкратце для людей несведущих написали бы почему так.
int — скалярный тип
Integer — класс.
А почему new String[1024] занимает больше памяти, чем new Integer[1024]?
И то и другое объекты, а массивы содержат только ссылки на объекты, разве нет?
Integer хранит число в поле int, а String — как массив char-ов + дополнительные поля:

private final char value[];

/** The offset is the first index of the storage that is used. */
private final int offset;

/** The count is the number of characters in the String. */
private final int count;

/** Cache the hash code for the string */
private int hash; // Default to 0
> а массивы содержат только ссылки на объекты, разве нет?
нет, тогда бы размер любого массива был — countof(array) * sizeof(Pointer), а это не так.
да и глупо так делать, new[] выделяет сразу кусок под все объекты.
а разница заключается в том, что классы отличаются, Integer хранит один набор полей (скажем 4 int-поля), а String — другой (3 int-поля и 10 char'ов, к примеру).
new Integer[] выделяет память только под указатели, поэтому размер массива-то как раз примерно «countof(array) * sizeof(Pointer)». Но в сабже память считается вместе с самими объектами, которые создаются отдельно в цикле (см. исходники).
ужаснах)
хотя для джавы это не так критично, с предвыделенной из системного пула памятью.
Иначе это и не может для полиморфных объектов. Если создается, например, массив Shape[], то там могут быть и Point и Circle и Polygon, совершенно разные объекты с различными полями и конструкторами.

Конечно, в C++ можно сделать new Shape[N], но кому такой массив нужен? Надо делать массив указателей (для полиморфных объектов, а не просто структур), а в Яве фактически все объектные переменные как указатели.
речь идёт именно о «new Class[N]».
а не о «new Class[]».
во втором случае само собой дозволяется в таком массиве хранить классы-потомки, и линейное выделение памяти невозможно и неэффективно, ибо размеры объектов разные.
Ниасилил разницы new Class[N] и new Class[]. В Яве разницы нет. А в С++ что такое new Class[]?
Автор наверное имел ввиду, что в C++
Shape* shapes = new Shape[10];

круче чем

Shape[10] shapes;
кроме Shape в обоих вариантах ничего в массив не поместить, если я ничего не путаю, давно на С++ не пишу
ужаснах)

Насколько я понимаю, этот «ужас» позволяет лучше работать когда память сильно фрагментирована.
Тут вобще всё страшно смешано, базовые типы — классы, коллекции и с теми и с другими. У простого смертного возникнет уйма вопросов вида «А почему так». Автору надо было как то разделить таблицу на какие то логические группы.

И ещё такой вопрос, я уже несовсем точно помню, но разве ArrayList(1024) не выравнивается до какого то другого значения?
Помнится, меня еще на Ява конференции поразил доклад, что сортировка массива интов быстрее сортировки массива Integer раза в 3, потому что Collection.sort использует разные алгоритмы для базовых типов и для объектов.
Посмотрел я тут на масштаб бедствия с памятью и думаю, может сделать врапперы для списков базовых типов. Что-то вроде IntArrayList ~= ArrayList. Аналогично IntHashMap<int, V> ~= HashMap<int, V> итп. Под частную задачу можно получить приличный перформанс и мемори буст.
Они пишут, что реализцют collections api. То что я предлагаю его не реализует вродебы.
Спасибо за наводку! Ушел тестить скорость…
С утра непонятливый. Что вы хотели сказать «IntArrayList ~= ArrayList»? и в чем состоит ваша идея?
Это не вы непонятливый, это парсер порезал генерик после ArrayList<int>
А писал я с сафари айпэда, который (сафари, не айпэд) пока я писал этот небольшой коммент успел упасть 2 раза…

boolean contains(int o);

IntIterator iterator();

int[] toArray();

boolean add(int e);
Предположительно все это должен знать любой JAVA разработчик

Что именно? Знать приведенную таблицу наизусть? :) Или просто понимать, чем int от Integer отличается и что такое строки и символы в Java?
Да уж, есть есть гораздо более важные знания для разработчика. Например, как правильно реализовать equals() и hashCode() для persistence entities — сколько народу на собеседованиях ловятся на том, что думают, раз Блока прочитали, значит все про Java знают.

Размеры структур данных, может быть, имеют значение в случае разработки под эмбеддед системы, но даже там далеко не во всех случаях — уж Андроид с устройствами с 256мб памяти и выше к Эмбеддед относится лишь отчасти.
Это справедливо только для Java? На C# всегда думал, что int — это ключевое слово для C#, а Integer для .NET. А по сути это одно и тоже. Ваша статья меня напугала ))
Возможно, Integer из Java — это упакованный int/
int и Integer, string и String, bool и Boolean и др. — это всё одно и тоже без исключений. Просто написание разное. (с) Рихтер
Как это — «одно и то же без исключений»?
Я вас сейчас ещё сильнее напугаю. Разница между примитивными типами и классами-оболочками не только в весе. Они ещё и хранятся по разному. Первый в стеке, а вторые в куче.
Страшно?
Интересно, что byte[], short[], int[] и long[] логично весят по-разному (~2 раза), Short[], Integer[], Long[] — одинаково и много, а Byte[] — намного меньше. Какое-то хитрое выравнивание памяти в объектах.
Byte[] намного меньше, т.к. новые объекты типа Byte не создаются — их всего 256, и они все закэшированы.
Объекты типа Short, Integer, Long занимают одинаково по 16 байт (на 32-битной платформе), т.к. заголовок объекта в HotSpot состоит из 8 байт, и сами объекты аллоцируются с выравниванием в 8 байт.
Тогда думаю критично, как инициализируется Byte[]. Если делать new Byte(i), то, вероятно, кэш не сработает.
Да, тут та же ситуация, что и со String.
Интересная информация, спасибо, добавил в избранное.
Все-таки интересно почему размер Double[] увеличился, а Integer[] нет — у них же суть одна?..
Каждый раз, когда ты пишешь int i вместо short i, сотни пользователей вынуждены докупать планку памяти.
… и умирает котенок
Тогда уж лучше byte. Потому что в результате случайного автобоксинка short станет Short, а оно по размеру ничем не отличается от Integer. Хотя это странно… неужели они везде используют int?
А для PHP, Javascript подобных табличек нет? Недавно обнаружил, что $a=''; забирает 168 байт.
Преждевременная оптимизация зло, но знать такие вещи конечно нужно :)
Sign up to leave a comment.

Articles