How precisely do Java arrays use memory in HotSpot (i.e. how much slop)?
Asked Answered
C

1

7

C malloc implementations typically don't allocate the precise amount of memory requested but instead consume fixed-size runs of memory, e.g. with power-of-two sizes, so that an allocation of 1025 bytes actually takes a 2048-byte segment with 1023 bytes lost as slop.

Does HotSpot use a similar allocation mechanism for Java arrays? If so, what's the right way to allocate a Java array such that there's no slop? (E.g. should the array length be a power of two or maybe power of two minus some fixed amount of overhead?)

Chronister answered 11/6, 2015 at 16:29 Comment(6)
Let's assume you need an array to store 1025 bytes. Let's assume Java allocates 2048 bytes of memory for that array, leaving 1023 bytes unused. What would you gain in creating an array of 2048 bytes to store 1025 bytes? Now you'll have to handle the unused 1023 bytes yourself, and store the actual length of the array somewhere, and pass it as argument instead of just passing the array, instead of letting the JVM do it for you. And the amount of consumed memory will be the same. It's a no-brainer. The right way to allocate an array is to allocate an array with the length you need.Emeric
Honestly, I wouldn't worry about how a JVM implementation handles memory. The joys of using a managed language such as Java are that memory isn't simply one giant array, you never need to worry about buffer overruns or memory corruption from out-of-bounds problems or wayward pointers, and you (almost) never need to worry about object clean up. Open yourself to the zen of Java.Bashful
malloc has a bunch of constraints a garbage-collected language doesn't have to worry about at all. I wouldn't assume Java has to worry about those things.Slicer
@JBNizet For the purpose using an array as a buffer, one might calculate the array size depending on operation params and then round it up to the next allocation boundary. So while not the common case, there are use cases where you might want to know.Oosperm
Maybe you can squeezed a few more "free" array members. However, the JVM does a whole lot of malloc-ing behind the scenes, and on those chunks it then shuffles, merges, and splits as necessary to support GC. Any optimization you may perform will be tied to a particular OS + VM + run-time options + what have you; are you sure it's worth it?. There is no one-to-one relationship between your array sizes and the actual mallocs happening underneath in a long-running program.Sappanwood
@JBNizet When implementing a growable buffer, if I know that 1025 bytes consume 2048 bytes, I might as well allocate 2048 bytes when I need 1025 so that I don't need to reallocate for growth between 1025 and 2048.Chronister
O
5

If you're asking about the language, the answer is: Its not specified (same as for C)

If you're asking about a specific implementation, check out that implementation. I believe for Hotspot its 8 bytes granularity; that is object sizes are rounded up to the next granularity boundary. If the question is about the heap size increase when there isn't enough free heap, then it depends on implementation, GC settings, heap size params and so on; making it impractical to answer precisely.

EDIT: Using a small reflection hack, accessing the sun.misc.Unsafe class (Oracle JRE only), object references can be converted to memory addresses; output the addresses of two consecutively allocated arrays to check for yourself.

And I basically asked the same question here: Determine the optimal size for array with respect to the JVM's memory granularity (Answers include an example of using the Unsafe class to check for object size)

Oosperm answered 11/6, 2015 at 17:34 Comment(1)
I indeed tried to formulate my question to ask about HotSpot rather than Java in general. And looking at the answer to the other question, it looks like rounding up to the nearest 8-byte boundary is the answer. Thanks.Chronister

© 2022 - 2024 — McMap. All rights reserved.