开发者社区> 牧小农> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

JVM性能优化(二)垃圾回收算法详解(2)

简介: JVM性能优化(二)垃圾回收算法详解
+关注继续查看

2.4 复制算法


复制算法的核心就是,将原有的内存空间一分为二,每次只用其中的一块,在垃圾回收时,将正在使用的对象复制到另一个内存空间中,然后将该内存空间清空,交换两个内存的角色,完成垃圾的回收。

如果内存的垃圾对象较多,需要复制的对象就较少,这种情况下适合使用该方式并且效率比较高,反之,则不适合。

屏幕快照 2022-05-10 下午3.20.32.png

2.4.1 JVM中年轻代内存空间:


image.png


在GC开始的时候,对象只会存在于Eden区和名为 “From” 的Survivor区,Survivor区 “To” 是空的

紧接着进行GC,Eden区中所有存活的对象都会被复制到 “To” 区,而在 “From” 区中,仍存活的对象会根据他们的年龄值来决定去向,年龄达到一定值(年龄阈值,可以通过-XX:MaxTenuringThreshold来设置)的对象会被移动到年老代中,没有达到阈值的对象会被复制到 “To” 区域中。

经过这次GC后,Eden区和From区已经被清空,这个时候,“From” 和 “To” 会交换他们的角色,也就是新的 “To” 就是上次GC前的 “From” ,新的 “From” 就是上次GC前的 “To”,不管怎样,都会保证名为 To 的 Survivor区域是空的。

GC会一直重复这样的过程,知道 “To” 区被填满,“To” 区被填满之后,会将所有对象移动到年老代中

2.4.2 优缺点


优点:


在垃圾对象多的情况下,效率较高

清理后,内存无碎片

缺点:


在垃圾对象少的情况下,不适用,如:老年代内存

分配的2块内存空间,在同一个时刻,只能使用一半,内存使用率较低

2.4 分代算法


前面介绍了多种回收算法,没有算法都有自己的优点也有缺点,谁都不能替代谁,所以根据垃圾回收对象的特点进行选择,才是明智的选择。

分代算法其实就是这样,根据回收算法的特点进行选择,在JVM中,年轻代适合使用复制算法,老年代适合使用标记清楚或标记压缩算法。


三、垃圾收集器以及内存分配


上面我们介绍了垃圾回收的算法,还需要有具体的体现,在jvm中,实现了多种垃圾收集器,包括:串行垃圾收集器、并行垃圾收集器、CMS(并发)垃圾收集器,G1垃圾收集器,接下来,我们一个个的了解学习。


3.1、串行垃圾收集器


串行垃圾收集器,是指使用单线程进行垃圾回收,垃圾回收时,只有一个线程在工作,并且java应用中的所有线程都要暂停,等待垃圾回收的完成,这种现象称之为 STW(Stop-The-World)。

对于交互性较强的应用而言,这种垃圾收集器是不能够接收的。

一般在javaweb应用中是不会采用该收集器的。


3.1.1 编写测试代码

   // 实现:不断的产生新的数据(对象),随机的去废弃对象(垃圾)
    public static void main(String[] args) throws Exception {
        List<Object> list = new ArrayList<>();
        while (true){
            int sleep = new Random().nextInt(100);
            if(System.currentTimeMillis() % 2 ==0){
                //当前的时间戳,是偶数
                list.clear();
            }else{
                //向List中添加1000个对象
                for (int i = 0; i < 10000; i++) {
                    Properties properties = new Properties();
                    properties.put("key_"+i,"value_"+System.currentTimeMillis()+i);
                    list.add(properties);
                }
            }
            Thread.sleep(sleep);
        }
    }

3.1.2 设置垃圾回收为串行收集器


image.png


在程序运行参数添加2个参数,如下:


-XX:UseSerialGC:指定年轻代和老年代都是用串行垃圾收集器

-XX:PrintGCDetails:打印垃圾回收的详细信息

# 为了测试GC,将堆的初始值和最大内存都谁知为16M

-XX:+UseSerialGC -XX:+PrintGCDetails -Xms16m -Xmx16m


启动程序后,可以看到下面信息:


[GC (Allocation Failure) [DefNew: 4416K->511K(4928K), 0.0052836 secs] 4416K->1768K(15872K), 0.0053321 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]


[Full GC (Allocation Failure) [Tenured: 10943K->10943K(10944K), 0.0186019 secs] 15871K->14611K(15872K), [Metaspace: 3828K->3828K(1056768K)], 0.0186344 secs] [Times: user=0.02 sys=0.00, real=0.02 secs]


GC日志信息解读:

年轻代的内存GC前后的大小:


DefNew:表示使用的是串行垃圾收集器

4416K->511K(4928K): 表示,年轻代GC前,占有4416K内存,GC后,占有512K内存,总大小4928K

0.0052836 secs: 表示,GC所用的时间,单位为毫秒

**4416K->1768K(15872K):**表示,GC前,堆内存占有4416K,GC后,占有1973K,总大小为 15872K

Full GC: 表示,内存空间全部进行GC


版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
JVM之垃圾回收算法详解
JVM之垃圾回收算法详解
18 0
JVM详解 --- 垃圾回收机制
JVM详解 --- 垃圾回收机制
141 0
JVM性能优化 (一) 初识JVM(2)
JVM性能优化 (一) 初识JVM
14 0
shiro(二)shiro详解(2)
shiro(二)shiro详解
43 0
【JVM】JVM系列之垃圾回收(二)
如果不进行垃圾回收,内存迟早都会被消耗空,因为我们在不断的分配内存空间而不进行回收。除非内存无限大,我们可以任性的分配而不回收,但是事实并非如此。所以,垃圾回收是必须的。
26 0
【JVM】JVM系列之垃圾回收(二)(3)
  如果不进行垃圾回收,内存迟早都会被消耗空,因为我们在不断的分配内存空间而不进行回收。除非内存无限大,我们可以任性的分配而不回收,但是事实并非如此。所以,垃圾回收是必须的。
23 0
深入理解JVM虚拟机2:JVM垃圾回收基本原理和算法
    JVM GC基本原理与GC算法   Java的内存分配与回收全部由JVM垃圾回收进程自动完成。与C语言不同,Java开发者不需要自己编写代码实现垃圾回收。
1257 0
+关注
牧小农
业精于勤荒于嬉,行成于思毁于随。
134
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载