| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Java: Общие вопросы > Выделение памяти под массив |
| Автор: UnicornMirage 28.2.2006, 00:14 | ||
любой массив объектов в Java хранит ссылки на объекты (какими они ни были эти объекты). отсюда следует что все проинициализированные массивы будут занимать одинаковый объем памяти? (разумеется учитывается только массив ссылок на объекты а не сами проинициализированные объекты):
сколько байт занимает одна ссылка? |
| Автор: redrick 28.2.2006, 01:18 |
| Вобщем, в спецификации VM это не оговаривается. Одна ссылка может занимать сколько угодно, в зависимости от реализации. На практике, правда, это обычно 4 байта. А насчет одинаковости - опять же, скорее всего, но не обязательно, обязательно только то что по данной ссылке ты сможешь вытащить объект которым ее проинициализировал. |
| Автор: LSD 28.2.2006, 10:58 | ||
На 64-х битных машинах, скорее всего одна ссылка будет занимать 8 байт. А вообще это не сложно узнать:
|
| Автор: powerOn 28.2.2006, 11:58 | ||||
Простите, а зачем 4 раза сборщик мусора поднимать? |
| Автор: redrick 28.2.2006, 12:04 |
| для пущей лучшести =) |
| Автор: LSD 28.2.2006, 12:08 | ||
| А щоб наверняка 1. Вызов System.gc() не гарантирует, что сборщик будет реально вызван
2. Сборщик мусора инкрементальный, и может не все объекты очистить после первого вызова. Это уже обсуждалось, если найду кину ссылку. |
| Автор: UnicornMirage 28.2.2006, 14:15 |
| спасибо за ответы. теперь отвечу почему я задал такой вопрос - например есть задача - где необходимо выделить своеобразный КЭШ для объектов произвольного типа. размер КЕШа заранее известен, также известен его максимально-возможный размер.. и в этом случае целесообразнее использовать заранее выделенный массив ссылок на объекты, чем использовать коллекции или списки, т.к. это будет работать гораздо быстрее? |
| Автор: redrick 28.2.2006, 14:23 |
| если у тебя в кеше лежат большие объекты (уж побольше чем 4 или 8 байт) то, думаю, колекция маленьких ссылок не испортит тебе жизнь Вобщем незачем этот массив заранее выделять - ничего это не дает. |
| Автор: COVD 28.2.2006, 17:50 | ||
Быстрее будет заполняться, если вы заранее укажете правильный размер при создании коллекции. Потому что если не указывать, то любая коллекция будет расширяться по необходимости, а это означает создание нового внутреннего массива и копирование туда ссылок из старого. Этим во многих случаях можно пренебречь. Любая стандартная коллекция или лист требуют применения кастинга при извлечении обьектов. На это тоже не принято обращать внимания. Если же производительность - узкое место (редко, но бывает), то можно хранить в массиве конкретного типа. Не нужен кастинг и доступ по индексу - самый быстрый. |
| Автор: king 9.4.2006, 17:41 | ||
То что указатель занимает 4 байта понятно.. Но меня еще интересует другой вопрос : сколько занимает сам объект .. Немного модернизировал ваш код :
и получил : sizeof(Test[1038336]) = 20771840 bytes, 20.004930966469427 bytes/element т.е 20 байтов на элемент. Из них 4 идет на указатель.. а 16 на объект.. После эксперементов установил следующую закономерность : 0 полей - 8 байт 1 интовое поле - 16 байт 2 интовых поля - 16 байт 3 интовых поля - 24 байт 4 интовых поля - 24 байт 5 интовых поля - 32 байт т.е пустой клас занимает 8 байт, дальше идет выравнивание размера на 8 байт .. Это нормальное поведение для ява програмы? просто получается что большое количество объектов создавать не выгодно в яве.. в с++ можно делать структуры (это фактичнски те же самые классы) , но весят они именно столько , сколько от них ждешь |
| Автор: powerOn 9.4.2006, 19:21 |
| А класс Test как выглядит? |
| Автор: king 10.4.2006, 08:28 | ||||
|
| Автор: powerOn 10.4.2006, 11:28 | ||||||
В С++ структуры весять как сумма "масс" полей, но это структуры. В Java нет структур. В Java есть классы. А это означает, что любой класс, даже такой:
будет наследован от класса Object, который в свою очередь тоже требует определенного объема памяти. Это не недостаток языка, это его приемущество, поскольку если все классы имеют единого предка, то это означает возможность единого проведения операции для разных классов. Например, можно в колекцию добавлять объекты разных классов
, поскольку есть метод addElement(Object o). И не важно кто есть o. Это дает дополнительную гибкость. И вообще, если даже на MFC посмотреть, там тоже большинство классов унаследованны от CObject, который, вероятно, тоже занимает определенное место в памяти. |