Comments 43
Какая будет разница по потреблению памяти между конструкциями `new int[1024]` и `new Integer[1024]`?Сильно зависит от платформы, версии Java и ключей JVM.
Если int[1024] всегда занимает около 4K, то объем Integer[1024] может варьироваться от тех же 4K
(при -XX:+UseCompressedOops -XX:+AggressiveOpts) до 28K (при -XX:-UseCompressedOops).
Спасибо. Для меня очень полезная информация.
Вкратце для людей несведущих написали бы почему так.
int — скалярный тип
Integer — класс.
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
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'ов, к примеру).
нет, тогда бы размер любого массива был — 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], но кому такой массив нужен? Надо делать массив указателей (для полиморфных объектов, а не просто структур), а в Яве фактически все объектные переменные как указатели.
Конечно, в C++ можно сделать new Shape[N], но кому такой массив нужен? Надо делать массив указателей (для полиморфных объектов, а не просто структур), а в Яве фактически все объектные переменные как указатели.
речь идёт именно о «new Class[N]».
а не о «new Class[]».
во втором случае само собой дозволяется в таком массиве хранить классы-потомки, и линейное выделение памяти невозможно и неэффективно, ибо размеры объектов разные.
а не о «new Class[]».
во втором случае само собой дозволяется в таком массиве хранить классы-потомки, и линейное выделение памяти невозможно и неэффективно, ибо размеры объектов разные.
ужаснах)
Насколько я понимаю, этот «ужас» позволяет лучше работать когда память сильно фрагментирована.
Тут вобще всё страшно смешано, базовые типы — классы, коллекции и с теми и с другими. У простого смертного возникнет уйма вопросов вида «А почему так». Автору надо было как то разделить таблицу на какие то логические группы.
И ещё такой вопрос, я уже несовсем точно помню, но разве ArrayList(1024) не выравнивается до какого то другого значения?
И ещё такой вопрос, я уже несовсем точно помню, но разве ArrayList(1024) не выравнивается до какого то другого значения?
Помнится, меня еще на Ява конференции поразил доклад, что сортировка массива интов быстрее сортировки массива Integer раза в 3, потому что Collection.sort использует разные алгоритмы для базовых типов и для объектов.
Посмотрел я тут на масштаб бедствия с памятью и думаю, может сделать врапперы для списков базовых типов. Что-то вроде IntArrayList ~= ArrayList. Аналогично IntHashMap<int, V> ~= HashMap<int, V> итп. Под частную задачу можно получить приличный перформанс и мемори буст.
Посмотрел я тут на масштаб бедствия с памятью и думаю, может сделать врапперы для списков базовых типов. Что-то вроде IntArrayList ~= ArrayList. Аналогично IntHashMap<int, V> ~= HashMap<int, V> итп. Под частную задачу можно получить приличный перформанс и мемори буст.
С утра непонятливый. Что вы хотели сказать «IntArrayList ~= ArrayList»? и в чем состоит ваша идея?
Предположительно все это должен знать любой JAVA разработчик
Что именно? Знать приведенную таблицу наизусть? :) Или просто понимать, чем int от Integer отличается и что такое строки и символы в Java?
Да уж, есть есть гораздо более важные знания для разработчика. Например, как правильно реализовать equals() и hashCode() для persistence entities — сколько народу на собеседованиях ловятся на том, что думают, раз Блока прочитали, значит все про Java знают.
Размеры структур данных, может быть, имеют значение в случае разработки под эмбеддед системы, но даже там далеко не во всех случаях — уж Андроид с устройствами с 256мб памяти и выше к Эмбеддед относится лишь отчасти.
Размеры структур данных, может быть, имеют значение в случае разработки под эмбеддед системы, но даже там далеко не во всех случаях — уж Андроид с устройствами с 256мб памяти и выше к Эмбеддед относится лишь отчасти.
Это справедливо только для Java? На C# всегда думал, что int — это ключевое слово для C#, а Integer для .NET. А по сути это одно и тоже. Ваша статья меня напугала ))
Интересно, что byte[], short[], int[] и long[] логично весят по-разному (~2 раза), Short[], Integer[], Long[] — одинаково и много, а Byte[] — намного меньше. Какое-то хитрое выравнивание памяти в объектах.
Byte[] намного меньше, т.к. новые объекты типа Byte не создаются — их всего 256, и они все закэшированы.
Объекты типа Short, Integer, Long занимают одинаково по 16 байт (на 32-битной платформе), т.к. заголовок объекта в HotSpot состоит из 8 байт, и сами объекты аллоцируются с выравниванием в 8 байт.
Объекты типа Short, Integer, Long занимают одинаково по 16 байт (на 32-битной платформе), т.к. заголовок объекта в HotSpot состоит из 8 байт, и сами объекты аллоцируются с выравниванием в 8 байт.
Интересная информация, спасибо, добавил в избранное.
Все-таки интересно почему размер Double[] увеличился, а Integer[] нет — у них же суть одна?..
Каждый раз, когда ты пишешь int i вместо short i, сотни пользователей вынуждены докупать планку памяти.
А для PHP, Javascript подобных табличек нет? Недавно обнаружил, что $a=''; забирает 168 байт.
Преждевременная оптимизация зло, но знать такие вещи конечно нужно :)
Sign up to leave a comment.
Сравнение потребления памяти у разных структур хранения данных