Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to analyze the CAS of Unsafe and the principle of memory operation

2025-01-15 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Servers >

Share

Shulou(Shulou.com)05/31 Report--

How to analyze the principle of CAS and memory operation of Unsafe, I believe that many inexperienced people do not know what to do about it. Therefore, this paper summarizes the causes and solutions of the problem. Through this article, I hope you can solve this problem.

One of the major features of Java language is cross-platform, and provides a perfect memory management mechanism. But all these are provided by JVM, which cannot be realized if we want to access system memory resources directly, manage memory resources independently, and so on. So Java provides another magic class: Unsafe.

The Unsafe class is located in the sun.misc package. From the name point of view, this class is an unsafe class, in fact, it does encapsulate some unsafe operations!

The Unsafe class is defined as final like the String class, that is, it cannot be inherited. And Unsafe is designed as a singleton, and the constructor is private and can only be obtained through the getUnsafe method. In addition, the getUnsafe method sets restrictions so that only the crediting code can get an instance of this class. What are the credit codes? Of course, the classes in the JDK library are free to use.

After saying for a long time, we can't use this class, what's the point of talking about it?

Don't worry, Java doesn't recommend using it, but we can use it in two ways.

The first way is to let our code "grant credit" at startup. When running the program, specify the bootclasspath option to allow classes that use Unsafe instances to be loaded by the bootstrap class loader, so that the Unsafe instance can be safely obtained through the Unsafe.getUnsafe method.

This practice is rarely used, so it is recommended that you use the second method: use it through reflection.

Note that some IDE may not be very friendly. For example, eclipse displays "Access restriction..." Error, but if you run the code, it will work properly. If this error message is annoying, you can avoid it by setting the following:

Unsafe has 8 functions, and many accounts only talk about its CAS function.

As shown in the figure above, the 105API provided by Unsafe can be roughly divided into memory operations, CAS, Class related operations, object operations, thread scheduling, system information acquisition, memory barriers, array operations, and so on. Today I'll start with two big features: CAS and memory manipulation (it's a series of things related to "hand-in-hand teaching you to experience strong references, soft references, weak references, and virtual references through Java code" and "out-of-heap memory that 90% of programmers may not even know about").

The CAS operation mainly involves the following three API.

CAS is a technique that is often used to compare and replace and implement concurrent algorithms. The CAS operation contains three operands-- the memory location, the expected original value, and the new value. When performing the CAS operation, the value of the memory location is compared with the expected value, and if it matches, the processor automatically updates the location value to the new value, otherwise the processor does nothing. As we all know, CAS is an atomic instruction of CPU (cmpxchg instruction), which will not cause the so-called data inconsistency problem. The underlying implementation of CAS methods (such as compareAndSwapXXX) provided by Unsafe is the CPU instruction cmpxchg.

CAS is widely used in the implementation of java.util.concurrent.atomic related classes, Java AQS, CurrentHashMap and so on. For example, in the implementation of AtomicInteger, the static field valueOffset is the memory offset address of the field value, and the value of valueOffset is obtained in the static code block through the objectFieldOffset method of Unsafe when AtomicInteger initializes. In the thread-safe method provided in AtomicInteger, the value of the field valueOffset can be used to locate the memory address of the value in the AtomicInteger object, thus the atomic operation of the value field can be realized according to CAS.

For example, the following figure shows the memory diagram of an AtomicInteger object before and after the self-increment operation. The base address of the object is baseAddress= "0x110000", and the memory address valueAddress= "0x11000c" of value is obtained through baseAddress+valueOffset. Then an atomic update operation is performed through CAS, and if it succeeds, it will be returned, otherwise, continue to try again until the update is successful.

After talking about CAS, let's talk about the memory operation of Unsafe.

The main memory operations are the following 9 API.

I've already talked about it in two articles, "hand-in-hand teaching you to experience the differences between strong references, soft references, weak references, and virtual references through Java code," and "out-of-heap memory that 90% of programmers probably don't know." The objects created in Java are in the heap, which is the Java process memory controlled by JVM, and they follow the memory management mechanism of JVM. JVM will use garbage collection mechanism to manage heap memory. In contrast, out-of-heap memory exists in the memory area outside the control of JVM. The operation of out-of-heap memory in Java depends on the native method provided by Unsafe to operate on out-of-heap memory.

The reasons for using out-of-heap memory are:

Improvements to the garbage collection pause. Because out-of-heap memory is directly managed by the operating system rather than JVM, we can maintain a small size of in-heap memory when we use out-of-heap memory. Thus, the impact of the recovery pause on the application is reduced during GC.

Improve the performance of the program Icano operation. Usually, there is a data copy operation from in-heap memory to out-of-heap memory in the process of Icano communication, and it is recommended to store out-of-heap memory for temporary data that needs to be copied frequently and has a short life cycle.

DirectByteBuffer, which I mentioned earlier, is widely used in NIO frameworks such as Netty and MINA. The logic of DirectByteBuffer for the creation, use and destruction of out-of-heap memory is realized by the out-of-heap memory API provided by Unsafe.

The figure above is the DirectByteBuffer constructor. When creating a DirectByteBuffer, memory is allocated through Unsafe.allocateMemory, memory is initialized by Unsafe.setMemory, and then a Cleaner object is built to track the garbage collection of DirectByteBuffer objects, so that when DirectByteBuffer is garbage collected, the allocated out-of-heap memory is released together. The specific release is the PhantomReference virtual reference I mentioned earlier.

After reading the above, have you mastered the method of how to analyze the CAS and memory operation of Unsafe? If you want to learn more skills or want to know more about it, you are welcome to follow the industry information channel, thank you for reading!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Servers

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report