4 ms·
Java has an interesting pointer model between 32 bit and 64 bit pointers: Compressed OOps. A pointer to a data structure is shifted right by 3 a.k.a divided by
by hyperman1 8y ago
Java has an interesting pointer model between 32 bit and 64 bit pointers: Compressed OOps.
A pointer to a data structure is shifted right by 3 a.k.a divided by 8. You now have 35 bits and can addres 16GB. Data structures should be aligned on an 8 byte boundary.
At runtime, the pointer is expanded to 64 bit in a register, multiplied by 8, and the correct offset for a struct field is added.
So you can't point at individual bytes, and you have to shift, but you gain 4 bytes per pointer. It is said this hits the current sweet spot for Java.
- bogomipz 8y agoI believe this is why you sometimes see recommendations to no to set the JVM heap larger than 32 Gigs. Is this still the case though? Does JVM performance fall off a cliff without compressed pointers? Or is the issue more GC beyond 32 Gigs.
- lmm 8y agoThe advice I've heard is that there's no point setting a heap size between 32G and 48G: between those limits the bigger object references will cost you more space than you gain. Long pauses for full GC are a distinct issue that large heaps have. I believe the newer garbage collectors are designed to address this, but don't have much experience with them in practice.
- joemag 8y agoPerformance hit is barely noticeable for most apps. The biggest surprise is usually heap usage increase. You can increase your heap from 28 to 34 GB, and end up with less free memory.
- user5994461 8y agoA common misconception unfortunately. The heap is limited to roughly 30 GB, plus a bit of overhead. You will never run in 32bits mode if you set a 32GB heap, because overhead. From experience, a 30GB heap is similar to a 40GB in usable space. 32 vs 64 bits pointers respectively.
- bogomipz 8y agoSorry what is the common misconception? Exceeding a 32 gig heap size will cause the JVM to stop using compressed pointers? This seems to be widely accepted: https://www.elastic.co/guide/en/elasticsearch/guide/current/heap-sizing.html https://www.elastic.co/guide/en/elasticsearch/guide/current/... I understand there's overhead I wasn't suggesting that all 32 Gigs were useable
- adtac 8y ago>You now have 35 bits and can addres 16GB 32 GB, right? 2^32 is 4 GB, so 8 times that is 32 GB, unless I'm missing something? Edit: yep: https://wiki.openjdk.java.net/display/HotSpot/CompressedOops https://wiki.openjdk.java.net/display/HotSpot/CompressedOops
- hyperman1 8y agoMy docs spoke of 16GB. I assumed sun had the sign bit reserved for something. But we are still on Java 6 so maybe technology advanced a bit in the last 12 years ;-)
- simias 8y agoThat's interesting, do we know how big of a difference that makes for modern architectures? You do save some room for storing (and moving) pointers but you lose by having more padding for your alignment constraints and extra-shifting to "decompress" the pointers. More generally I suspect that this approach might make sense for a VM but I that it would lead to huge headaches in C code because the programmer would have to manage the "compressed" pointers explicitly in code unless the compiler was smart enough to handle it completely by itself (something that could be very tricky to do efficiently). It reminds me of the good old days of segmented memory with the mess surrounding near and far pointers. Still, I would be curious to see actual performance numbers for these various "64bits ISA with 32bit pointers" ABIs, it is true that 64bit pointers are pretty wasteful for many applications.
- pjmlp 8y agoNot necessarily, it could be handled in the MMU, we are after all discussing about kernel support.
- simias 8y agoI don't understand what you're proposing, what could be handled by the MMU? If you're talking about the address shifting I don't think that would work since AFAIK MMUs don't typically have sufficient granularity to map pointers at that scale. If you're talking about x32-style mapping then of course that works but then you still only have 32bits of address space.
- pjmlp 8y agoNaturally I am talking about x32-style mapping. Having only 32bits of address space wouldn't be a problem, isn't after all the goal of x32 to reduce memory consumption of processes that don't require more than 4GB? The mapping would just simply take place on a per-process basis.
- hyperman1 8y agoIn Java, it was mostly a no brainer: Objects were already aligned on 16byte boundaries, the extra shift is mostly free on modern hardware, and the optimizer is smart enough to compute the base only once if multiple fields are accessed - the common situation. But that's Java. In C, pointer casting makes it impossible to do this without help from the programmer: You simply can't stop the programmer to cast an invalid value to a pointer. In theory, a mode where char is 2, 4 or 8 physical bytes, but in practice, a lot of software would break.
- TheJoYo 8y agoyoure using java oops
- robocat 8y agoGood stack overflow answer here https ://stackoverflow.com/questions/25120546/trick-behind-jvms-compressed-oops which links to other resources. The main optimisation is that more data fits into the CPU cache so potential for more cache hits which leads to improved speed.