jvm-对象堆内存分代、对象堆内存垃圾回收器
内存分为新生代和老年代
cms
新生代,老年代,永久代,且是连续内存空间。jdk8已经没了永久代,而是元空间。
g1
内存也分代,但是g1垃圾回收器本身是不分新生代和老年代的,即既回收新生代又回收老年代,因为g1是分区,粒度更细,即每个代包含了多个分区,而且每个代的多个分区不是连续内存空间。
架构图
官方架构图
线程栈:局部变量、方法入参(也是局部变量),生命周期和线程一样,随着线程的结束而结束——其实方法结束的时候,就会结束,即方法结束会回收。
对象堆:对象本身,生命周期是如果没有引用,就会回收。垃圾回收,只和对象堆相关,和局部变量、类数据没有关系。
非对象数据:Class、Method等数据,非对象数据,生命周期和进程一样,因为类和方法等元数据是一直存在的。
垃圾回收器
垃圾回收器的发展史
1、单线程
缺点:会stw。
单线程:有新生代和老年代版本。
2、多线程
和单线程一样,因为是单线程的多线程版本,其他都一样。
缺点:也会stw。
多线程:有新生代和老年代版本。
3、cms
c是并发单词的意思。
为什么要设计cms?就是因为之前的都不能并发,因为要stw,cms可以并发,即不会stw。
4、吞吐量优先(parallel scavenge并行清除)
和多线程一样,也会stw,唯一的区别是:吞吐量优先。
吞吐量指总的停顿时间变小,那么总的服务时间就变大,总的服务时间变大,即吞吐量变大。
其实本质是降低回收频次,减少了总gc时间,但是单次耗时变大。
5、g1
最新的垃圾回收器,现在生产环境用的最多的仍然是cms,但是未来的趋势是,从分代变为分区。g1目前在生产环境只是试用期,可能会拿一些应用去试用。
架构图
注意:
jdk搭配使用不同垃圾回收器。
有连线的才可以搭配使用。
比如,jdk8默认是使用年轻代(吞吐量优先),老年代(多线程)。但是,生产环境的最佳实践是,配置为使用新生代(多线程),老年代(cms)。
按新生代和老年代分类
上面说了,内存是分代,垃圾回收器也是分代的,为什么要分代,就是为了更好的管理内存。
单线程和多线程,都有新生代和老年代版本。
吞吐量优先,只有新生代版本。
cms只有老年代版本。
g1,不分新生代和老年代,因为从g1开始,创造了一个新的概念,叫分区。虽然内存仍然是分代,即有新生代和老年代,但是垃圾回收器已经没有分代的概念了,而是分区的概念。分区是最小粒度单元,新生代和老年代分别包含了多个分区,新生代和老年代现在已经不是连续内存空间了。垃圾回收器,未来的趋势就是,从分代变为分区。
按单线程多线程分类
1、单线程(有新生代和老年代版本)
2、多线程(有新生代和老年代版本),是单线程的多线程版本,其他都一样。
吞吐量优先(只有新生代版本),也是多线程,只不过吞吐量优先。
按是否stop the world分类
会stw
单线程,多线程,都会stw。
不会stw
cms,也是多线程,并且是并发(cms的c就是并发concurrency的意思,cms是concurrency mark sweep,即并发标记清除),并发的意思是,垃圾回收线程不影响应用程序线程的执行,即可以同时执行,所以不会stw。
jdk8默认是新生代(吞吐量优先) + 老年代(多线程)
如何查看?
www.riceball.com.cn/articles/20…
www.riceball.com.cn/articles/20…
最佳实践?
目前一般会配置为使用cms,而不是默认的。cms目前在生产环境用的是最多的。
部分应用,会配置为使用g1。
作者:青乡java
链接:https://juejin.cn/post/7025809338698563591