📜 ⬆️ ⬇️

Array sizes in java

The sizes of objects in Java have already been discussed on Habré, for example, here or here . I would like to dwell in more detail on the dimensions of multidimensional arrays - a simple thing that has become unexpected for me.

Optimizing the computational algorithm from memory, I came across the fact that with certain (quite reasonable) input parameters, an array float is created [500] [14761] [2]. How much can it occupy in memory (on HotSpot 1.6.0_26 32bit, if anyone is interested)? I roughly estimated that 500 * 14 761 * 2 * sizeof (float) = 500 * 14 761 * 2 * 4 = 59,044,000 bytes, plus some kind of overhead. Having decided to check how actually, I used the Eclipse Memory Analyzer (incredibly magical thing, I recommend it!) And found that the “Retained Heap” for this array is 206,662,016 bytes ! A good overhead projector - 350%. Let's see why it happened.

I looked for what was being written on the Internet on this topic, and came across a rather clear article in English “ How to calculate the memory usage of a Java array ”. In short, the essence of the presentation is as follows:


')
This knowledge is enough. So we have at the end of the chain arrays float [2]. Their size is 2 floats (4 bytes each) + 12 bytes of the overhead projector - 20 bytes. Aligned to 8 - it turns out 24 bytes. In total, we have such arrays created in a heap of 500 * 14,761 - 7,380,500 pieces. In total, they weigh 177,132,000 bytes.

Then we have arrays float [14761] [] - arrays from 14,761 references to other arrays. Each such array occupies 14,761 links (4 bytes) + 12 bytes of overhead - 59,056 bytes (divided by 8 - no need to align). All these arrays are 500 pieces, which means they together weigh 29,528,000 bytes.

Finally, we actually have the array that we have got - float [500] [] [] - an array of 500 references to two-dimensional arrays. It occupies 500 * 4 + 12 = 2 012 , and even 4 bytes of alignment - 2 016 bytes.

Add up what happened: 177 132 000 + 29 528 000 + 2 016 = 206 662 016 - just the number that Memory Analyzer showed.

Immediately came up with the obvious solution: to order the array measurements in ascending order. Let's make float [2] [500] [14761] and the algorithm will not suffer from this. What size will be in this case?


In total, 59,060,056 bytes, the overhead projector is less than 0.03%, almost 150 megabytes of memory is saved.

From here follows the rule of thumb: if the dimensions of the array according to measurements are at least approximately known in advance, the measurements should be ordered in ascending order. In addition, be sure to use memory analyzers: learn a lot about your program.

Source: https://habr.com/ru/post/142409/


All Articles