Original | Java heap memory is shared by threads! Interviewer: Are you sure?

Original | Java heap memory is shared by threads! Interviewer: Are you sure?

△Hollis, a person with a unique pursuit of Coding△
Original | Java heap memory is shared by threads!  Interviewer: Are you sure?
This is Hollis’s 255th original sharing
author l Hollis
source l Hollis (ID: hollischuang)
Java as an object-oriented, cross-platform language, its objects, memory, etc. It is a difficult knowledge point, so even a beginner in Java must have some understanding of JVM more or less. It can be said that the relevant knowledge about JVM is basically a knowledge point that every Java developer must learn, and it is also a knowledge point that must be tested during an interview.

In the memory structure of JVM, the two common areas are heap memory and stack memory (if not specified, the stack mentioned in this article refers to the virtual machine stack). Regarding the difference between the heap and the stack, many developers are also Like Shu Jiazhen, there are many books or articles on the Internet that are probably introduced like this:


1、堆是线程共享的内存区域,栈是线程独享的内存区域。
2、堆中主要存放对象实例,栈中主要存放各种基本数据类型、对象的引用。

However, the author can tell everyone responsibly that neither of the above two conclusions are completely correct.

This article first takes you to understand why I say "heap is a memory area shared by threads, and stack is a memory area exclusively shared by threads." This sentence is not completely correct! ? Regarding the relevant knowledge of the JVM memory structure, you can read JVM memory structure VS Java memory model VS Java object model, never thought that the interview question of JVM memory structure can be so difficult to ask? Wait for the article.

Before getting into the subject, please allow me to ask a question that seems to have nothing to do with this question: How does the memory allocation process of Java objects ensure thread safety?

How does the memory allocation process of Java objects ensure thread safety?

We know that Java is an object-oriented language. The objects we use in Java need to be created. In Java, there are many ways to create an object, but in any case, the object needs to be created in the process Perform memory allocation.
In the memory allocation process of the object, the reference of the object mainly points to this memory area, and then the initialization operation is performed.

However, because the heap is globally shared, there may be multiple threads requesting space on the heap at the same time. Then, in a concurrent scenario, if two threads successively refer to the same memory area, what should be done.
Original | Java heap memory is shared by threads!  Interviewer: Are you sure?

In order to solve this concurrency problem, the memory allocation process of the object must be controlled synchronously. But we all know that no matter which synchronization scheme is used (actually the virtual machine may use CAS), it will affect the efficiency of memory allocation.

The allocation of Java objects is a high-frequency operation in Java, so people think of another way to improve efficiency. Here we focus on a HotSpot virtual machine solution:

每个线程在Java堆中预先分配一小块内存,然后再给对象分配内存的时候,直接在自己这块”私有”内存中分配,当这部分区域用完之后,再分配新的”私有”内存。

This kind of scheme is called TLAB allocation, namely Thread Local Allocation Buffer. This part of the Buffer is divided from the heap, but is exclusive to the local thread.

What is TLAB

TLAB is a dedicated space divided by the virtual machine in the eden of the heap memory, which is exclusive to the thread. When the TLAB function of the virtual machine is started, when the thread is initialized, the virtual machine allocates a TLAB space for each thread, which is only used by the current thread, so that each thread has a separate space. If memory needs to be allocated, Allocate on their own space so that there is no competition, which can greatly improve the efficiency of allocation.

Have you noticed the descriptions of "thread exclusive", "only for the current thread", and "each thread individually" in the above description?

Therefore, because of the TLAB technology, the heap memory is not completely shared by threads, and some of the space in the eden area is allocated to threads exclusively.

It is worth noting here that we say that TLAB is exclusively shared by threads, but it is exclusively shared by threads in the action of "allocation". As for reading, garbage collection and other actions, they are shared by threads. And there is no difference in usage.
Original | Java heap memory is shared by threads!  Interviewer: Are you sure?

In other words, although each thread will apply for a TLAB in the heap memory during initialization, it does not mean that the memory in this TLAB area is completely inaccessible to other threads. Other threads can still read it, but it cannot Allocate memory in the area.

Moreover, after the TLAB is allocated, it does not affect the movement and recycling of the object. That is to say, although the object may be allocated memory through TLAB at the beginning and stored in the Eden area, it will still be garbage collected or moved to Survivor Space or Old Gen. Wait.
Original | Java heap memory is shared by threads!  Interviewer: Are you sure?

One more thing to note is that we say that TLAB is allocated in the eden area, because the eden area itself is not too large, and the memory of the TLAB space is also very small, which only occupies 1% of the entire Eden space by default. Therefore, there must be some large objects that cannot be directly allocated in TLAB.

When encountering large objects that cannot be allocated in TLAB, the objects may still be allocated in the eden area or the old generation, but this kind of allocation requires synchronization control, which is why we often say: small objects are allocated more than large objects More efficient.

Problems caused by TLAB

Although to a certain extent, TLAB greatly improves the speed of object allocation, but TLAB is not without any problems.

As we said earlier, because the TLAB memory area is not very large, it may often be insufficient. There is such an example in "Real Java Virtual Machine":

For example, the TLAB space of a thread is 100KB, of which 80KB has been used. When another 30KB object needs to be allocated, it cannot be allocated directly in the TLAB. In this case, there are two solutions:

1. If the space required by an object exceeds the remaining space in the TLAB, the object is directly allocated in the heap memory.

2. If the space required by an object exceeds the remaining space in the TLAB, the current TLAB is discarded, and the TLAB space is re-applied for memory allocation again.

The above two schemes have their own advantages and disadvantages. If scheme 1 is adopted, there may be an extreme situation, that is, there is only 1KB left in the TLAB, which will cause most objects that need to be allocated in the future to be directly allocated in the heap memory.

If scheme 2 is adopted, there may be frequent abandonment of TLAB and frequent application of TLAB. We know that although the memory allocated on TLAB is exclusive to threads, there may indeed be conflicts in the process of dividing TLAB memory from the heap. Therefore, the allocation process of TLAB actually requires concurrent control. However, frequent TLAB allocations lose the meaning of using TLAB.

In order to solve the problems of these two solutions, the virtual machine defines a refill_waste value, which can be translated as "maximum wasted space".

When the requested memory is greater than refill_waste, it will choose to allocate in the heap memory. If it is less than the refill_waste value, the current TLAB will be discarded, and the TLAB will be recreated for object memory allocation.

In the previous example, the total space of TLAB is 100KB, 80KB is used, and the remaining 20KB. If the value of refill_waste is set to 25KB, then if the memory of the new object is greater than 25KB, the heap memory is allocated directly. If it is less than 25KB, the previous memory will be discarded. For the TLAB, reallocate a TLAB space to allocate memory for the new object.

Related parameters used by TLAB

The TLAB function can be turned on or off. You can specify whether to turn on TLAB distribution by setting the -XX:+/-UseTLAB parameter.

TLAB defaults to 1% of the eden area. You can set the percentage of Eden space occupied by TLAB space through the option -XX:TLABWasteTargetPercent.

By default, the TLAB space will be continuously adjusted during operation to make the system reach the best operating state. If you need to disable the automatic adjustment of the TLAB size, you can use -XX:-ResizeTLAB to disable it, and use -XX: TLABSize to manually specify the TLAB size.

TLAB's refill_waste can also be adjusted. The default value is 64, which means that about 1/64 of the space is used as refill_waste. Use the parameter: -XX: TLABRefillWasteFraction to adjust.

If you want to observe the usage of TLAB, you can use the parameter -XX+PringTLAB to track.

to sum up

In order to ensure the thread safety in the memory allocation process of the object, the HotSpot virtual machine provides a technology called TLAB (Thread Local Allocation Buffer).

When the thread is initialized, the virtual machine allocates a TLAB space for each thread, which is only used by the current thread. When memory needs to be allocated, it is allocated in its own space, so that there is no competition, and the allocation efficiency can be greatly improved.

Therefore, the phrase "heap is a memory area shared by threads" is not completely correct, because TLAB is a part of heap memory. It is indeed shared by threads in reading, but it is exclusive to threads in memory allocation.

The space of TLAB is actually not large, so large objects may still need to be allocated directly in the heap memory. Then, the memory allocation step of the object is to try TLAB allocation first. After the space is insufficient, determine whether it should go directly to the old generation, and then determine whether to allocate again eden or allocate in the old generation.
Original | Java heap memory is shared by threads!  Interviewer: Are you sure?

Say a few more words

I believe that after reading this article, some of the authors may feel that the author is a bit too "critical" and "critical". There may be some impatient people who just read the beginning and turned directly to the end of the article to prepare.

Regardless of whether you agree with what the author said: "The saying that the heap is a memory area shared by threads is not entirely correct." This is actually not important. The important thing is that when it comes to heap memory, thread sharing, and object memory allocation, you can think of another TLAB that is more special.

Sometimes, the most terrifying thing is not that you don't know, but that you don't know.

In addition, TLAB is just an optimization solution of HotSpot virtual machine, and there is no regulation on TLAB in the Java virtual machine specification. Therefore, it does not mean that all virtual machines have this feature.

The overview of this article is based on the HotSpot virtual machine. The author did not deliberately "generalize the whole", but because the HotSpot virtual machine is currently the most popular virtual machine, most of which are by default when we discuss it. Based on HotSpot.

Hey, every time I write some technical articles, there will be a lot of people spraying, and the spraying angles are all odd and strange, so I have to say a few more words to make up for it. Anyway, any kind of discussion is welcome, because even if it is spraying, there may not be an opponent!

About the Author: Hollis, has a unique quest for Coding people, the current Alibaba technical experts, personal technology blogger, technical articles, the amount of reading the whole network of tens of millions, "three classes programmer" joint author.

  • MORE | More exciting articles-The
    gap is big, I did not expect that the technology used by adult websites will be a few blocks away from us!
    6 websites that accept private work, you have the technology and the money!
    It took a month to sort out the company’s core microservice architecture. It turned out not to be too difficult...
    20 microservice interview questions that you have to memorize. The interview will definitely be asked.

If you like this article,
please press
Original | Java heap memory is shared by threads!  Interviewer: Are you sure?
and hold the QR code and follow Hollis. Forward it to the circle of friends. This is my greatest support.
Good article, I am reading ❤️

Hollis

Guess you like

Origin blog.51cto.com/13626762/2544188