Source
How Java Memory Works?. Before we move on to the performence… | by Berkay Haberal | Jul, 2023 | Stackademic (medium.com)
Before we move on to the performence things, we need to learn that what is really going on in the background of JVM (Java Virtual Machine).
在开始探讨性能问题之前,咱们须要理解 JVM(Java 虚拟机)的后盾到底产生了什么。
This is the starting point of every developer who wants to learn and tune performance in order to gain some speed. So let’s dive into the world of codes.
这是每一个想要学习和调整性能以进步速度的开发人员的终点。因而,让咱们进入代码的世界。
In Java, memory management is handled by JVM automatically to store your variables, classes, fields and beyond… The first thing we will learn is in JVM, memory splitted into two regions.
在 Java 中,内存治理由 JVM 主动解决,用于存储变量、类、字段和其余内容 …… 咱们首先要理解的是,在 JVM 中,内存分为两个区域。
One of them is called Stack and the other one is Heap.
其中一个称为 堆(Stack),另一个称为 堆(Heap)。
What is Stack? 什么是堆栈?
First region we are going to learn is Stack.
咱们要学习的第一个区域是 栈。
In JVM, stack is very efficent approach to memory management and not only just one but also every thread has its own stack region.
在 JVM 中,堆栈是一种十分无效的内存治理办法,不仅是一个线程,每个线程都有本人的堆栈区域。
In stack, instantiated fieds are added to memory one on another just like its name stacking.
在堆栈中,实例化的文件一个接一个地增加到内存中,就像堆栈的名字一样。
As you can see, this area is not big enough to store objects so what is happening is primitive types and object pointers can be stored directly instead of storing a whole object.
正如你所看到的,这个区域不够大,无奈存储对象,因而能够间接存储 原始类型 和对象指针,而不是存储整个对象。
And when it is time to remove, first object needs to be removed first because like I said, data is stacked, we can’t reach the bottom unless we remove those items.
当须要删除时,须要先删除第一个对象,因为就像我说的,数据是重叠在一起的,如果不删除这些我的项目,咱们就无奈达到底部。
What is Heap? 什么是堆?
Now, let’s look at the other region called Heap.
当初,让咱们来看看另一个名为 堆的区域。
As you can see it from the GIF, heap size is bigger than stack because heap is the main region for holding objects.
从 GIF 中能够看到,堆的大小大于栈,因为堆是寄存对象的次要区域。
Every created object is held in heap and its reference is helding in stack.
每个创立的对象都寄存在堆中,其援用寄存在栈中。
Like figure shown below
如下图所示
public List<String> test() {
String newString = "test";
List<String> testList = new ArrayList<>();
testList.add(newString);
return testList;
}
On the contrary, there is just one heap that application has.
相同,应用程序只有一个堆。
That sounds quite reasonable because we might have more than one big object that passes one method to another.
这听起来很正当,因为咱们可能有不止一个大对象,这些对象会将一个办法传递给另一个办法。
So basically, stack is used for local variables and there could be many stacks but they all use one heap to store the objetcs.
因而,堆栈基本上是用于局部变量的,可能有很多堆栈,但它们都应用一个堆来存储对象。
Those objects pointers are held in stack so when we want to pass objects between methods, we are not copying objects like in stack, we are passing its reference.
这些对象的指针保留在堆栈中,因而当咱们要在不同办法之间传递对象时,咱们不是像在堆栈中那样复制对象,而是传递其援用。
Furthermore, heap is not one, solid region at all. If you zoom in to the heap, you will see 4 different areas
此外,堆基本不是一个残缺的区域。如果放大堆,你会看到 4 个不同的区域
Actually those are called generations. Heap is builded on two main generations. One of them is young and the other one is old. Young generation is divided into three spaces. Eden, survivor zero and survivor one spaces. It will be more clear when you learn what they do. Created objects are first placed in eden space. Then eden is fulled, objects are moved to the survivor one or survivor zero. After, created objects are placed in eden again. When eden is full, both eden and survivor zero or one will be moved to the survivor zero or one. If objects are moved more than five, those objects are now placed in old generation. This means, now those objects are needed and will live in old generation unless it looses its pointer. If there are no variables in the stack that holds its reference, this means that object is eligible for garbage collection. Last one is so important for performance issues and thus we need to learn how Java memory works to understand it.
实际上,这就是所谓的 “ 代 ”。堆建设在两个主代上。一个是Young,另一个是Old。Young 代分为三个空间。Eden、survivor0 和survivor1。
当你理解了它们的作用后就会更分明了,新创建的对象首先被搁置在 Eden。
而后 Eden 被填满,存活对象被挪动到 survivor1 或survivor0。解决之后,后续创立的对象会再次搁置在 Eden 中。
如果挪动的对象超过 5 次,这些对象就会被搁置在 Old 中。
这意味着,当初这些对象都是须要的,除非失去指针,否则它们都将留在 Old 中。
如果堆栈中 没有任何对象援用,这意味着该对象合乎垃圾回收的条件。
最初一条对于性能问题十分重要,因而咱们须要学习 Java 内存的工作原理以便了解它。
One more room for Metaspace please! 请为 Metaspace 多留一个地位!
Besides these regions, there is one more region in memory I want to mention. ==Metaspace is the region where application’s metadata is stored.==
除了这些区域外,我还想提到内存中的另一个区域:== 元空间(Metaspace):是存储应用程序元数据的区域。==
Most of the times, we don’t need to know what is going on in metaspace due to its mission.
大多数时候咱们并不需要晓得元空间中产生了什么。
And there is one more mission it has and that is holding static variables, methods and classes in it.
但它还有一个使命,那就是 保留动态变量、办法和类。
This is why static keyword is accessable from anywhere because they are helding in metaspace so every thread can reach it easily.
这也是为什么动态关键字能够从任何中央拜访,因为 它们保留在元空间中,所以每个线程都能够轻松拜访。
Can we tune this size? 咱们能调整这个尺寸吗?
Absolutely. There are flags we can use that tells JVM what to do when we are starting the application. We can some of these flags
当然能够。咱们能够应用一些标记来通知 JVM 在启动应用程序时要做什么。咱们能够应用其中一些标记:
- -XmsNg to set initial size
- -XmxNg to set maximum size
- -XX:NewRatio=N ratio of the young generation to the old generation
- -XX:NewSize=N initial size of the young generariton
- -XX:MaxNewSize=N maximum size of the young generation
-XmsNg
:用于设置 初始 大小。-XmxNg
:用于设置 最大 大小。-XX:NewRatio=N
:新生代 与老年代的 N 比值 。-XX:NewSize=N
: 新生代 的初始大小 。-XX:MaxNewSize=N
:年老代的 最大尺寸。
And we’ve reached our deadline. Before we move onto the Garbage Collection, it was essential to learn how Java memory works to have a better understanding about Garbage Collection. I hope I see you in my next article. Happy Coding!
在学习垃圾回收之前,咱们有必要理解一下 Java 内存的工作原理,以便更好地了解垃圾回收。心愿咱们在下一篇文章中再见。编码高兴