Предположим, мне нужно отметить элементы в списке. Это можно сделать, установив биты в BitSet на true или сохранив индексы отмеченных элементов в списке. Я хочу сравнить потребление памяти решением BitSet с решением, использующим ArrayList. В тесте я случайным образом устанавливал некоторые биты в BitSet, а затем сохранял индексы установленных битов в ArrayList.
Когда я проверяю кучу в VisualVM, использование кучи (после G C), как сообщается, составляет 210M. Тем не менее, heapdump сообщает, что сохраненный размер ArrayList составляет 280 МБ, а сохраненный размер BitSet - 4 МБ.
Как любой оставшийся размер (или сумма сохраненных размеров) может быть больше используемой кучи?
private final static Random random = new Random();
public static void main(String[] args) throws IOException {
double oneProbability = 1./3;
BitSet hits = new BitSet();
int trials = 30_000_000;
// set random bits to true
for (int i = 0; i < trials; i++) {
hits.set(i, random.nextDouble() <= oneProbability);
}
// store the indices of the true bits in a list
List<Integer> hitIndices = new ArrayList<>(hits.cardinality());
hits.stream().forEach(hit -> hitIndices.add(hit));
// wait for heap inspection
System.in.read();
System.out.println("Number of bits set to one = " + hits.cardinality());
System.out.println("BitSet size in MiB = " + hits.size() / 8. / 1024 / 1024);
// 20 bytes per Integer instance
long arrayListBytes = 20 * hitIndices.size();
System.out.println("Estimated retained size of the ArrayList in MiB = " + arrayListBytes / 1024 / 1024);
}
Вывод на консоль:
Number of bits set to one = 10002754
BitSet size in MiB = 4.0
Estimated retained size of the ArrayList in MiB = 190
Использование кучи на VisualVM имеет размер 210M, а ArrayList и BitSet имеют наибольшие сохраняемые размеры.
![heap-dump](https://i.stack.imgur.com/hL1XH.png)
Информация о версии:
JVM: Java HotSpot(TM) 64-Bit Server VM (13.0.2+8, mixed mode, sharing)
Java: version 13.0.2, vendor Oracle Corporation
VisualVM: 2.0.1 (Build 200326); platform 20191008-unknown-revn
System: Mac OS X (10.14.6), x86_64 64bit