我们将从4个方面学习Java GC机制,1,内存是如何分配的;2,如何保证内存不被错误回收(即:哪些内存需要回收);3,在什么情况下执行GC以及执行GC的方式;4,如何监控和优化GC机制。
Java内存区域
了解Java GC机制,必须先清楚在JVM中内存区域的划分。在Java运行时的数据区里,由JVM管理的内存区域分为下图几个模块:
JVM内存分为: 栈内存(Stack)、堆内存(Heap)、方法区(Method Area) 和 原生方法栈(也叫 本地方法栈,Native Method Stack)
我们平时最关心的是堆内存,其中,堆内存又分为新生代(young generation)、老年代(old generation) 。
其中 方法区,在有些技术文章中,被称为 永久代(pem generation)
123
For Java, JVM also contains heap and stack in runtime data area. Objects and arrays are created on heap, method frames are pushed to stack. One heap is shared by all threads, while each thread has its own stack. The following diagram shows this:
123
属于堆内存 |
年轻代(young generation)(也称新生代) |
划分为三个Eden、survivor0、surivor1三部分。默认按照8:1:1的比例进行分配,有的地方会是From(Eden)和To(Eden) |
存储着新分配的和较年轻的对象 |
|
属于堆内存 |
老年代(old generation) |
内存比例较大,如果内存不足时会触发MajorGC也就是Full GC。 |
存储着长寿的对象 |
|
属于方法区 |
永久代(permanent generation) |
比如保存常量池 |
存储着那些需要伴随整个JVM生命周期的对象,比如,已加载的对象的类定义或者String对象内部Cache。 |
|
上面表格的图形式:
[root@ssp02 ~]# sudo -u nobody /usr/local/jdk/bin/jmap -heap 16942
Attaching to process ID 16942, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 24.80-b11
using parallel threads in the new generation.
using thread-local object allocation.
Concurrent Mark-Sweep GC
Heap Configuration:
MinHeapFreeRatio = 40
MaxHeapFreeRatio = 70
MaxHeapSize = 2684354560 (2560.0MB) #总的heap大小=年轻代+年老代
NewSize = 1610612736 (1536.0MB)
MaxNewSize = 1610612736 (1536.0MB) #年轻代是1536MB
OldSize = 5439488 (5.1875MB)
NewRatio = 2
SurvivorRatio = 22 #(Eden/Survivor=22, Eden+Survivor*2=1536,得到Survivor是64,Eden是1408)
PermSize = 134217728 (128.0MB)
MaxPermSize = 402653184 (384.0MB)
G1HeapRegionSize = 0 (0.0MB)
Heap Usage:
New Generation (Eden + 1 Survivor Space):
capacity = 1543503872 (1472.0MB)
used = 645286656 (615.393310546875MB)
free = 898217216 (856.606689453125MB)
41.806610770847485% used
Eden Space:
capacity = 1476395008 (1408.0MB)
used = 635014624 (605.5971374511719MB)
free = 841380384 (802.4028625488281MB)
43.01116033033891% used
From Space:
capacity = 67108864 (64.0MB)
used = 10272032 (9.796173095703125MB)
free = 56836832 (54.203826904296875MB)
15.306520462036133% used
To Space:
capacity = 67108864 (64.0MB)
used = 0 (0.0MB)
free = 67108864 (64.0MB)
0.0% used
concurrent mark-sweep generation: ##这里表示年老代
capacity = 1073741824 (1024.0MB) ##年老代是2560 - 1536 ,正好是1024
used = 83465272 (79.59868621826172MB)
free = 990276552 (944.4013137817383MB)
7.773309201002121% used
Perm Generation:
capacity = 134217728 (128.0MB)
used = 77542656 (73.950439453125MB)
free = 56675072 (54.049560546875MB)
57.773780822753906% used
26890 interned Strings occupying 3034088 bytes.