0

A quick google search results in surprisingly nothing.

My question is as follows:

For 32-bit architecture - 2^32 bytes would be the memory space = 4GB So for a Java heap of 4 GB, we need a pointer of size 32 bits = 4 bytes.

However, by the concept of compressed oop, the JVM can still use the 4 byte pointer upto a heap size of 32 GB.

Thinking about it, 32 GB = 4 GB * 2^3. It means we actually need 3 more bits but somehow these bits are getting encoded/decoded by JVM during the storage/access.

I found these pages inaccessible : http://wikis.sun.com/display/HotSpotInternals/CompressedOops https://wikis.oracle.com/display/HotSpotInternals/CompressedOops

Can someone explain me the wizardry that is going on behind the scenes?

To Mods: I found an existing question, but that points to https://wikis.oracle.com/display/HotSpotInternals/CompressedOops. This wiki doesn't exist anymore, can you please allow this question so long that someone points me to an alternate in-depth link. Please.

Edit:

@Markus Mikkolainen response is the simplest and easiest explanation I have found : they are offsets and they are used to index 8 byte blocks and not one byte blocks since objects are 8 byte aligned.

rents
  • 768
  • 1
  • 7
  • 22
  • I found the link after posting - https://wiki.openjdk.java.net/display/HotSpot/CompressedOops – rents Sep 01 '15 at 17:32
  • 2
    In Windows 32-bit you only have 1.2 - 1.5 GB of continuous virtual memory available. In Java 8, you can address up to 64 GB heap using 32-bit references. It increases the object alignment from 8 bytes to 16 bytes. – Peter Lawrey Sep 01 '15 at 17:46
  • If I am correct, does that mean the minimum size a java object will have on heap would be 16 bytes? (because an object starting from say 9th bytes won't be representable in memory?) – rents Sep 01 '15 at 17:58
  • 1
    I would instead say that the minimum space an object will use is 16 bytes including header and object alignment. If you turn off the TLAB with `-XX:-UseTLAB` you can see the exact amount of space each object allocates. – Peter Lawrey Sep 01 '15 at 20:57
  • yes that's what I meant. So that will also mean a single Character (wrapper) = 2 bytes (underlying char) with its usual object header of 12 bytes (x64 compressed oop) will have 2 bytes of padding. Or a char array of 1 char will take 32 bytes (16 byte object header + 2 bytes + 14 bytes padding). Need to test this with JOL. – rents Sep 01 '15 at 21:18
  • I am using Java 1.8.0_51 but it tells me that objects are being 8 bytes aligned. Perhaps this will happen only if heap size >32 GB to save memory wastage or maybe a command line argument to configure that. thanks for the Java 8 example, now I understand things more clearly. – rents Sep 01 '15 at 21:28
  • 1
    Correct you need a 32 GB <= heap < 64 GB to see a default alignment change to 16 bytes, you can set this from the command line if you wish. – Peter Lawrey Sep 02 '15 at 07:11

1 Answers1

2

http://docs.oracle.com/javase/7/docs/technotes/guides/vm/performance-enhancements-7.html#compressedOop

does this answer your question, they are offsets and they are used to index 8 byte blocks and not one byte blocks since objects are 8 byte aligned.

Markus Mikkolainen
  • 3,397
  • 18
  • 21
  • A very stupid question: Since a 32 bits system can access 2^32 objects i.e. memory locations and a 32-bit processor has word size of 32 bits = 32 data lines = 4 bytes, why is the RAM limited to 2^32 * 8 bits = 4 GB and not 2^32 *32 bits. Is it because the OS wants to write to one byte at a time and not 4 bytes at a time (to prevent memory wastage due to object alignment )? – rents Sep 01 '15 at 17:56
  • The hardware CAN read a byte anywhere it wants due to backwards compatibility, but it just is very inefficient in doing it. – Markus Mikkolainen Sep 01 '15 at 17:58
  • @MarkusMikkolainen are you saying yes to my queries in the above comment? – rents Sep 01 '15 at 18:00
  • It is not OS related, it is related to the intel architecture and caching etc. – Markus Mikkolainen Sep 01 '15 at 18:01
  • oh right, so I will reframe my question: why is the RAM limited to 2^32 * 8 bits = 4 GB and not 2^32 *32 bits. Is it because the processor wants to be capable to read/write to one byte at a time and not 4 bytes at a time (to prevent memory wastage due to object alignment ) – rents Sep 01 '15 at 18:06
  • due to backwards compatibility an x86 and most other processors need to be able to do byte-based addressing I think. – Markus Mikkolainen Sep 01 '15 at 18:11
  • http://stackoverflow.com/questions/1054657/memory-alignment-on-a-32-bit-intel-processor – Markus Mikkolainen Sep 01 '15 at 18:12
  • Most stupidities in x86 are because of legacy. If you want nice clean architectures , look at RISCs – Markus Mikkolainen Sep 01 '15 at 18:13