JVM
垃圾收集器
更多讨论的是堆,java是面向对象
到底什么对象能成为GC Root(虚拟机栈中的本地变量表),可达性分析,
由GC Root判断当前对象是否是垃圾
heap.hprof文件可以看到相关信息,GC Root等
回收算法
1、标记清除。但是会产生碎片,空间不连续;耗时,效率比较低
清除不是真正置空,而是把需要清除的对象地址保存在空闲的地址列表。下次有对象需要加载时候,判断垃圾的位置空间是否够,如果够,就存放。
2、复制算法。空间浪费,解决空间不连续
3、标记整理。移动式的回收算法,按照内存地址依次排列,未被标记的对象被清除,给新对象分配内存时,jvm只需要持有一个内存的起始地址就可以,这比维护空闲列表少了许多开销。
4.增量收集算法,前面垃圾算法都会使得应用程序挂起,所有有了增量收集算法。
每次收集,垃圾收集线程只收集一小片区域,接着切换到应用程序线程,依次反复,直到垃圾收集完成。
但是,线程切换和上下文转换的消耗,会是得垃圾回收成本上升,造成系统吞吐量下降。
5.分区算法。G1.
为了更好控制GC产生的停顿时间,将一块大的内存区域分割成多个小块,根据目标的停顿时间,每次合理地回收若干个小区域,而不是整个堆空间,从而减少一次GC所产生的停顿。
每个小区域独立使用,独立回收,这种算法好处是可以控制一次回收多少个小区间。
我们需要将算法到堆当中的那一块进行落地,就产生垃圾收集器,不需要考虑算法的细节
垃圾收集器
适用于不同代(堆)
上图可以看到,垃圾收集器适用于哪个代
新生代:复制算法,适用于少量对象存活场景(朝生夕死)
老年代:标记-清除/整理
Serial:复制算法,单线程,缺点:业务代码线程暂停
ParNew:复制算法,多线程。(并行,垃圾回收线程一起)效率高
Parallel Scavenge:复制算法,并行,更加关注吞吐量(垃圾收集时间越短,吞吐量越大)
Serial Old:标记整理
Parallel Old:标记整理,关注吞吐量
CMS:Concurrent Mark Sweep,并发类的垃圾收集器(用户线程和垃圾回收线程可以同时进行),关注停顿时间, jvm调优:停顿时间和吞吐量
G1
1.9 默认
尝试着满足最小的停顿时间,可以设置时间,不是像CMS,不能设置时间
初始标记,可达性标记那些对象是垃圾对象,
并发标记,和用户线程同时进行执行
最终标记,
筛选回收,对堆内存各个region进行重新布局,region空间使用率大,不先进行回收,有选择性的进行回收,设置停顿时间,进行选择性回收
region
G1可以设置停顿时间,jvm调优就是停顿时间和吞吐量
查看当前收集器
jps -l
jinfo -f
jvm调优