auto commit
This commit is contained in:
parent
299d08eeaa
commit
4a58b4a43d
18
notes/JVM.md
18
notes/JVM.md
|
@ -197,6 +197,8 @@ PhantomReference<Object> pf = new PhantomReference<Object>(obj);
|
|||
|
||||
### 1.3 方法区的回收
|
||||
|
||||
因为方法区主要存放永久代对象,而永久代对象的回收率比新生代差很多,因此在方法区上进行回收性价比不高。
|
||||
|
||||
在方法区主要是对常量池的回收和对类的卸载。
|
||||
|
||||
常量池的回收和堆中对象回收类似。
|
||||
|
@ -213,10 +215,10 @@ PhantomReference<Object> pf = new PhantomReference<Object>(obj);
|
|||
|
||||
### 1.4 finalize()
|
||||
|
||||
当一个对象可被回收时,如果该对象有必要执行 finalize() 方法,那么就有可能可能通过在该方法中让对象重新被引用,从而实现自救。
|
||||
|
||||
finalize() 类似 C++ 的析构函数,用来做关闭外部资源等工作。但是 try-finally 等方式可以做的更好,并且该方法运行代价高昂,不确定性大,无法保证各个对象的调用顺序,因此最好不要使用。
|
||||
|
||||
当一个对象可被回收时,如果需要执行该对象的 finalize() 方法,那么就有可能可能通过在该方法中让对象重新被引用,从而实现自救。
|
||||
|
||||
## 2. 垃圾收集算法
|
||||
|
||||
### 2.1 标记-清除算法
|
||||
|
@ -240,7 +242,7 @@ finalize() 类似 C++ 的析构函数,用来做关闭外部资源等工作。
|
|||
|
||||
主要不足是只使用了内存的一半。
|
||||
|
||||
现在的商业虚拟机都采用这种收集算法来回收新生代,但是并不是将内存划分为大小相等的两块,而是分为一块较大的 Eden 空间和两块较小的 Survior 空间,每次使用 Eden 空间和其中一块 Survivor。在回收时,将 Eden 和 Survivor 中还存活着的对象一次性复制到另一块 Survivor 空间上,最后清理 Eden 和 Survivor。HotSpot 虚拟机的 Eden 和 Survivor 的大小比例默认为 8:1,保证了内存的利用率达到 90 %。如果每次回收有多于 10% 的对象存活,那么一块 Survivor 空间就不够用了,需要依赖于老年代进行分配担保,也就是借用老年代的空间。
|
||||
现在的商业虚拟机都采用这种收集算法来回收新生代,但是并不是将内存划分为大小相等的两块,而是分为一块较大的 Eden 空间和两块较小的 Survior 空间,每次使用 Eden 空间和其中一块 Survivor。在回收时,将 Eden 和 Survivor 中还存活着的对象一次性复制到另一块 Survivor 空间上,最后清理 Eden 和 使用过的那一块 Survivor。HotSpot 虚拟机的 Eden 和 Survivor 的大小比例默认为 8:1,保证了内存的利用率达到 90 %。如果每次回收有多于 10% 的对象存活,那么一块 Survivor 空间就不够用了,此时需要依赖于老年代进行分配担保,也就是借用老年代的空间。
|
||||
|
||||
### 2.3 标记-整理算法
|
||||
|
||||
|
@ -250,7 +252,7 @@ finalize() 类似 C++ 的析构函数,用来做关闭外部资源等工作。
|
|||
|
||||
### 2.4 分代收集算法
|
||||
|
||||
现在的商业虚拟机采用分代收集算法,它使用了前面介绍的几种收集算法,根据对象存活周期将内存划分为几块,不同块采用适当的收集算法。
|
||||
现在的商业虚拟机采用分代收集算法,它根据对象存活周期将内存划分为几块,不同块采用适当的收集算法。
|
||||
|
||||
一般将 Java 堆分为新生代和老年代。
|
||||
|
||||
|
@ -377,13 +379,21 @@ Region 不可能是孤立的,一个对象分配在某个 Region 中,可以
|
|||
|
||||
## 4. 内存分配与回收策略
|
||||
|
||||
对象的内存分配,也就是在堆上分配。主要分配在新生代的 Eden 区上,少数情况下也可能直接分配在老年代中。
|
||||
|
||||
### 4.1 优先在 Eden 分配
|
||||
|
||||
大多数情况下,对象在新生代 Eden 区分配,当 Eden 区空间不够时,发起 Minor GC;
|
||||
|
||||
关于 Minor GC 和 Full GC:
|
||||
|
||||
- Minor GC:发生在新生代上,因为新生代对象存活时间很短,因此 Minor GC 会频繁执行,执行的速度一般也会比较快。
|
||||
- Full GC:发生在老年代上,老年代对象和新生代的相反,其存活时间长,因此 Full GC 很少执行,而且执行速度会比 Minor GC 慢很多。
|
||||
|
||||
### 4.2 大对象直接进入老年代
|
||||
|
||||
提供 -XX:PretenureSizeThreshold 参数,大于此值的对象直接在老年代分配,避免在 Eden 区和 Survivor 区之间的大量内存复制;
|
||||
|
||||
### 4.3 长期存活的对象进入老年代
|
||||
|
||||
JVM 为对象定义年龄计数器,经过 Minor GC 依然存活且被 Survivor 区容纳的,移动到 Survivor 区,年龄加 1,每经历一次 Minor GC 不被清理则年龄加 1,增加到一定年龄则移动到老年区(默认 15 岁,通过 -XX:MaxTenuringThreshold 设置);
|
||||
|
|
Loading…
Reference in New Issue
Block a user