Original address: http://blog.csdn.net/seatalks/article/details/52981819
In this article, let's talk about compressed oops (a compressed normal object pointer). It is one of the optimization techniques of the JVM. Why should we put forward the concept of compressed oops? That's because the 32-bit and 64-bit architectures are different. Next, we will briefly review the 64-bit architectural features, and then go further into the discussion of compressed oops. Finally, we use a small example to see how it works. Since this small example is very simple, we do not need any IDE to help write its code.
In fact, compressed oops is not useful on a 32-bit machine, and it is closed by default in the previous version of Jdk6u23. So in this article we are using a 64-bit JDK and the version is higher than the 6u23 version. In our experiment, we used only one memory analysis tool,--industry standard Eclipse Memory Analyzer tool (version 1.5).
1.32-bit vs. 64-bit
The comparison of 32-bit and 64-bit was raised after 2000. However, the 64-bit CPU has long been used in the supercomputer domain, but only in recent years 64-bit CPUs have become the mainstream configuration on the PC. The shift from 32-bit to 64-bit is definitely not a simple job, because almost everything, from hardware to the operating system, has to change. Java is also introducing a 64-bit virtual machine in this trend of reform.
In the 32-to 64-bit transition, the greatest benefit is memory capacity . In a 32-bit system, the width of the memory address is 32 bits, which means that the maximum memory space we can get is 2^32 (or 4 G) bytes. This volume, if placed on a PC with only 640KB of memory, is just like infinity. But for now even a phone with 1G of memory is a low match today, we can not think so! In a 64-bit machine, theoretically, the amount of memory we can get is 2^64 bytes, which is a very large number (ridiculously huge). Unfortunately, this is only a theoretical value, and in reality, because there are a lot of hardware and software constraints, we can get much less memory. For example, the Windows 7 ultimate system can only support 192GB of memory. Many people may say "192GB is great", but compared with 2^64, it is really small, really. Well, we talked for a while, the importance of 64 people we also know, then we will talk about what compressed oops can do for us.
2. Overview of compressed Oops
"There is no free lunch in the world." It's also expensive to get a huge amount of memory in a 64-bit machine. In general, an application that runs on a 64-bit machine will spend more memory. And if it is not the kind of small program that can not be remembered, this cost can not be ignored. and compressed oops is using a 32-bit class pointer in a 64-bit environment (class pointer), which can help us save some memory space, but make sure the memory is not 32GB. Next, let's talk about how an object is represented in Java.
2.1. object Representations in Java
Let's start with a small example to help us understand how the object (objects) is represented in Java. We first assign a value to an integer object. When you write the following code:
New Integer (23);
The compiler actually allocates much more space to this object in the heap than 32 bits. The values for shaping numbers in Java are 32 bits, but each object contains some "head" content . These headers are different in different VMS, and are different in 32-bit and 64-bit virtual machines. In a 32-bit virtual machine, the length of each "field" of the head is a word word (4 bytes). In a 64-bit virtual machine, the range of the number of shapes is 32 bits long, but the length of the other fields increases to 8 bytes (one word length in 64-bit machines). If you think that this is the difference, I will hehe! Objects are aligned in memory, meaning that in a 64-bit machine, the memory of an object can be divisible by 64. And the main thing we're going to make is the class pointer (class pointer) called "Klass" in the hotspot virtual machine. From this, we can see that the length of the Klass in a normal 64-bit virtual machine is 8 bytes, but after starting compressed oops, it becomes 4 bytes.
2.2. Implementation of compressed Oops
Oop actually represents a normal object pointer (ordinary object pointer). These object pointers are the same length as the machine's local pointers, so the oops is 32 bits long on a 32-bit machine and 64 bits long on a 64-bit machine. But in compressed oops we can use a 32-bit long pointer on a 64-bit machine.
The key to compressed oops is whether the memory is addressed by byte or by word address. If you address by byte, we can get the contents of each byte in memory, but we also need to address each byte. In a 32-bit environment, this restricts you to only 2^32 bytes of memory. But if you use word-coding, you can still access so many blocks of memory, but each memory block is now a word and no longer a byte. In a 64-bit machine, one word is 8 bytes. This will make the JVM's address last three bits 0. Java uses the move (shifting) three-bit to achieve the purpose of expanding memory and realizing compressed oops.
3. Implementation of the compressed Oops
To see the effect of compressed oops, let's write a simple application. We use a LinkedList object list of 2 million shaping objects.
To achieve the purpose of viewing the heap status, we use the Eclipse Memory Analyzer tool to analyze the results.
In this case, we don't use eclipse or any other IDE, so we created a file named Integerapplication.java with a text editor. Knock the following code into the file. Note that the file name is identical to the Java class name!
Importjava.util.LinkedList; Importjava.util.List; ImportJava.util.Scanner; Public classintegerapplication { Public Static voidMain (string[] args) {List<Integer> intlist =NewLinkedlist<>(); for(inti=0;i<2000000;i++) {Integer number=NewInteger (1); Intlist.add (number); } Scanner Scanner=NewScanner (system.in); System.out.println ("Application is running ..."); String tmp=Scanner.nextline (); System.exit (0); } }
At the command-line prompt, CD to the directory where the file is located, and then compile it with the following command line.
Now we should get a Integerapplication.class file. Next, we run this file two times. First open compressed Oops, the second time off.
Since compressed oops is turned on by default in the JVM above the 6u32 version, we can run it directly at the command prompt by typing the following command.
Java integerapplication
There is a scanner object in the source code above. It is used to keep your program running until you type something to terminate the program. If you see "Application is running ..." at the command prompt, you can open the Memory analyzer. Based on your machine, it's possible to wait for a while, because it's going to do some initialization work.
Select the acquire HEAP dumping ... option from the File menu
You can see a Process selection window. Select "Integerapplication" and then click "Finish".
After that, you can see the main interface of the Memory analyzer. In the toolbar, select the Historical Analysis button at the location shown.
You can then see the information for all the objects in the program. Here is a little example of the information we have in the case of compressed oops open.
Next, we'll close compressed oops. To turn it off, we can use the-xx:-usecompressedoops logo. You do not need to recompile your program, type the following command directly at the command line:
The next steps are the same as above. Here is the result of closing the compressed oops:
As we thought, memory usage increased. Heap memory is mainly occupied by two types of objects, one is list nodes, the other is integers. 2 million shaping numbers require 32 million bytes of space in the compressed Oops environment, and 48 million bytes of space are required when the compressed oops is closed. The result of this simple little example is the same as we expected.
2000000* (128/8) = 32000000 or megabytes
2000000* (192/8) = 48000000 or megabytes
If we take a closer look at the second equation, we use 192 instead of 160 in the diagram before we introduced the Java object. The reason is that Java is byte-addressable, so the address is aligned with the nearest 8 bytes, and here is the 192-bit.
4. Summary
The example provided here may be somewhat unsatisfactory, but it can reflect the actual situation. If the H2 database is used as a test case, compressed oops can reduce the heap size from 3.6MB to 3.1MB. This also means that there are more than 14% available heaps. Obviously, there is no harm in using compressed oops, and it may be good for you. An understanding of some of the details of the compiler can help you write efficient code.
Introduction of compressed references in Compressedoops:java