powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / PriorityQueue<Integer>: на хранение 1 млн элементов (все - единицы) нужно > 10 Мб. Why ?
8 сообщений из 8, страница 1 из 1
PriorityQueue<Integer>: на хранение 1 млн элементов (все - единицы) нужно > 10 Мб. Why ?
    #38224421
ozzmosis
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Здравствуйте.

Имеется очередь с приоритетом, в которую натолкан 1 млн, причем все элементы равны числу 1:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
package DataStructures;
import java.util.*;
public class PQexplore2 {
    public static void main(String[] args){
        new PQexplore2().run();
    }
    void run() {
        final int N = 1000000;
        long t0=System.currentTimeMillis();
        PriorityQueue<Integer> pq = new PriorityQueue<Integer>();
        for (int i = 0; i < N; i++) {
            pq.add(1);
        }
        System.out.println("Done in "+(System.currentTimeMillis()-t0)+" ms, pq.size="+pq.size());
        System.out.println("Runtime.getRuntime().totalMemory(): " + Runtime.getRuntime().totalMemory() );
    }
}


Несколько раз позапускав этот класс, пришел вот к этому:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
D:\JAVA\1Probe\build\classes>java -Xms2048k  -Xmx10240k  DataStructures/PQexplore2
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
        at java.util.Arrays.copyOf(Arrays.java:2760)
        at java.util.Arrays.copyOf(Arrays.java:2734)
        at java.util.PriorityQueue.grow(PriorityQueue.java:238)
        at java.util.PriorityQueue.offer(PriorityQueue.java:269)
        at java.util.PriorityQueue.add(PriorityQueue.java:251)
        at DataStructures.PQexplore2.run(PQexplore2.java:12)
        at DataStructures.PQexplore2.main(PQexplore2.java:5)

D:\JAVA\1Probe\build\classes>java -Xms2048k  -Xmx10241k  DataStructures/PQexplore2
Done in 250 ms, pq.size=1000000
Runtime.getRuntime().totalMemory(): 11776000

1'000'000 int-чисел должен вроде бы укладываться в 4'000'000 байта.
Ну ладно, еще какие-то там накладные расходы могут быть, 10-20%(?)

Аппетит более 10 мегов обусловлен тем, что вместо самих чисел в коллекцию пишутся объекты класса-обёртки Integer или чем-то еще ?
И как понять, сколько на самом деле занимает в памяти некий созданный объект, если у меня их много ?
...
Рейтинг: 0 / 0
PriorityQueue<Integer>: на хранение 1 млн элементов (все - единицы) нужно > 10 Мб. Why ?
    #38224437
ozzmosis
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
И еще. Если заменить
Код: java
1.
pq.add(1);

на
Код: java
1.
pq.add(32767);

- то аппетит еще больше вырастет:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
D:\JAVA\1Probe\build\classes>java -Xms2048k  -Xmx20480k  DataStructures/PQexplore2
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
        at java.util.Arrays.copyOf(Arrays.java:2760)
        at java.util.Arrays.copyOf(Arrays.java:2734)
        at java.util.PriorityQueue.grow(PriorityQueue.java:238)
        at java.util.PriorityQueue.offer(PriorityQueue.java:269)
        at java.util.PriorityQueue.add(PriorityQueue.java:251)
        at DataStructures.PQexplore2.run(PQexplore2.java:12)
        at DataStructures.PQexplore2.main(PQexplore2.java:5)

D:\JAVA\1Probe\build\classes>java -Xms2048k  -Xmx20481k  DataStructures/PQexplore2
Done in 672 ms, pq.size=1000000
Runtime.getRuntime().totalMemory(): 22347776

Раз на хранение единиц памяти требовалось меньше, чем на 32767, то понятно, что JVM упаковывает числа, поступающие в коллекцию. Соотношение остается почти тем же: 22347776 / 8000000 = 2.79 vs 11776000 / 4000000 = 2.94 (см предыдущий пост).
То есть, на хранение каждого байта реальной информации яве надо почти 3 байта памяти
...
Рейтинг: 0 / 0
PriorityQueue<Integer>: на хранение 1 млн элементов (все - единицы) нужно > 10 Мб. Why ?
    #38224492
ozzmosis
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Кажись, понял. Если число элементов заранее известно, надо задать его в конструкторе, чтобы ява не делала "упреждающие расширения" коллекции.
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
package DataStructures;
import java.util.*;
public class PQexplore2 {
    public static void main(String[] args){
        new PQexplore2().run();
    }
    void run() {
        final int N = 1000000;
        long t0=System.currentTimeMillis();
        PriorityQueue<Integer> pq = new PriorityQueue<Integer>( N );
        for (int i = 0; i < N; i++) {
            pq.add(1);
        }
        System.out.println("Done in "+(System.currentTimeMillis()-t0)+" ms, pq.size="+pq.size());
        System.out.println("Runtime.getRuntime().totalMemory(): " + Runtime.getRuntime().totalMemory() );
    }
} 


Код: plaintext
1.
2.
D:\JAVA\1Probe\build\classes>java -Xms2048k -Xmx10240k DataStructures/PQexplore2
Done in 125 ms, pq.size=1000000
Runtime.getRuntime().totalMemory(): 6033408
...
Рейтинг: 0 / 0
PriorityQueue<Integer>: на хранение 1 млн элементов (все - единицы) нужно > 10 Мб. Why ?
    #38224508
J.Serge
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ozzmosisЗдравствуйте.

1'000'000 int-чисел должен вроде бы укладываться в 4'000'000 байта.
Ну ладно, еще какие-то там накладные расходы могут быть, 10-20%(?)

Аппетит более 10 мегов обусловлен тем, что вместо самих чисел в коллекцию пишутся объекты класса-обёртки Integer или чем-то еще ?
И как понять, сколько на самом деле занимает в памяти некий созданный объект, если у меня их много ?

Ты прикалываешься?
Зачем ты смотришь на Runtime.getRuntime().totalMemory() ?
Смотри хотя бы на используемую память: Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()
Далее, pq держит ссылки на объекты. Ссылка - 4 или 8 байтов, в зависимости от JRE (и настроек JVM).
Соот-но 4 или 8 MB.
Плюс сами объекты. 1 - это Integer, который кэшируется (кэшируется от -128 до 127, но это можно менять).
А 32767 - это Integer, который каждый раз создается заново. Т.е. еще плюс 4MB.

Точные размеры объектов скажут всякие профилеры. Можно попробовать java.lang.instrument.Instrumentation#getObjectSize(), но я бы не стал зацикливаться на точном знании размера сложных объектов.
Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory() достаточно :)
...
Рейтинг: 0 / 0
PriorityQueue<Integer>: на хранение 1 млн элементов (все - единицы) нужно > 10 Мб. Why ?
    #38224665
ozzmosis
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
J.SergeТы прикалываешься?
Зачем ты смотришь на Runtime.getRuntime().totalMemory() ?
Смотри хотя бы на используемую память: Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()
Далее, pq держит ссылки на объекты. Ссылка - 4 или 8 байтов, в зависимости от JRE (и настроек JVM).
Соот-но 4 или 8 MB.
Плюс сами объекты. 1 - это Integer, который кэшируется (кэшируется от -128 до 127, но это можно менять).
А 32767 - это Integer, который каждый раз создается заново. Т.е. еще плюс 4MB.я не прикалывался; просто не знал этого. Спасибо за ответ, стало понятнее.
...
Рейтинг: 0 / 0
PriorityQueue<Integer>: на хранение 1 млн элементов (все - единицы) нужно > 10 Мб. Why ?
    #38224670
ozzmosis
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
J.SergeПлюс сами объекты. 1 - это Integer, который кэшируется (кэшируется от -128 до 127, но это можно менять ).Как это сделать ?
...
Рейтинг: 0 / 0
PriorityQueue<Integer>: на хранение 1 млн элементов (все - единицы) нужно > 10 Мб. Why ?
    #38224674
rdm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ozzmosisJ.SergeПлюс сами объекты. 1 - это Integer, который кэшируется (кэшируется от -128 до 127, но это можно менять ).Как это сделать ?
-Djava.lang.Integer.IntegerCache.high=<size>
или JVM:

-XX:AutoBoxCacheMax=<size>
...
Рейтинг: 0 / 0
PriorityQueue<Integer>: на хранение 1 млн элементов (все - единицы) нужно > 10 Мб. Why ?
    #38224729
ozzmosis
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
rdm,

псб!
...
Рейтинг: 0 / 0
8 сообщений из 8, страница 1 из 1
Форумы / Java [игнор отключен] [закрыт для гостей] / PriorityQueue<Integer>: на хранение 1 млн элементов (все - единицы) нужно > 10 Мб. Why ?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]