JVM调优

目录

JVM启动参数

 实际例子

基础知识

垃圾回收器

Serial + Serial Old串行

Parallel + Parallel Old吞吐量优先

CMS响应时间优先

CMS回收过程可以分为哪些步骤?

​CMS的问题 

调优步骤

新生代调优

新生代比例越大越好吗

老年代调优


 

JVM启动参数

 实际例子


import java.util.ArrayList;

/**
 *  演示内存的分配策略
 */
public class Demo2_1 {
    private static final int _512KB = 512 * 1024;
    private static final int _1MB = 1024 * 1024;
    private static final int _6MB = 6 * 1024 * 1024;
    private static final int _7MB = 7 * 1024 * 1024;
    private static final int _8MB = 8 * 1024 * 1024;

    // -Xms20M -Xmx20M -Xmn10M -XX:+UseSerialGC -XX:+PrintGCDetails -verbose:gc -XX:-ScavengeBeforeFullGC

    public static void main(String[] args) throws InterruptedException {
        ArrayList<byte[]> list = new ArrayList<>();
        list.add(new byte[_8MB]);
    }

}

VM options:

-Xms20M -Xmx20M -Xmn10M -XX:+UseSerialGC -XX:+PrintGCDetails -verbose:gc -XX:-ScavengeBeforeFullGC

堆内存初始值 20 M

堆内存最大值 20M

新生代大小 10M

老年代  10M

使用UseSerialGC 串行的回收器

PrintGCDetails 输出GC 的消息

调优 调的就是堆空间,但是调优之前先要学会看gc日志,然后工具命令的使用jstat jps jmap jinfo

new Thread(() -> {
            ArrayList<byte[]> list = new ArrayList<>();
            list.add(new byte[_8MB]);
            list.add(new byte[_8MB]);
            System.out.println("kiki");
        }).start();

        System.out.println("sleep....");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

线程的内存溢出 不会导致主线程的结束,线程结束后分配的对象也会随之被回收。

基础知识

JVM垃圾回收_trigger333的博客-CSDN博客

垃圾回收器


Serial + Serial Old串行

堆内存较小,适合个人电脑,不然要耗费很长时间

新生代单线程收集器,标记和清理都是单线程,优点是简单高效;

 

Parallel + Parallel Old吞吐量优先

新生代收并行集器,实际上是Serial收集器的多线程版本,在多核CPU环境下有着比Serial更好的表现;

堆内存较大 多核cpu 适合 服务器,gc总时间短 适合科学计算等任务

分布式计算

可以设置的参数由 timeratio 一般设置为19  也就是0.05,表示GC暂停的时间不能大于程序运行时间的0.05。垃圾回收器会根据用户自定义的参数动态调整堆的大小。堆越大,一般来说垃圾回收的次数就会变少,不过每次垃圾回收的时间会变多。

 

CMS响应时间优先

Concurrent Mark Sweep。

看名字就知道,CMS是一款并发、使用标记-清除算法的gc。

CMS是针对老年代进行回收的GC。

在一些对响应时间有很高要求的应用或网站中,用户程序不能有长时间的停顿,CMS 可以用于此场景。

 

 

CMS回收过程可以分为哪些步骤?

(1)初试标记:初试标记仅仅只是标记一下GC Roots能直接关联到的对象,速度很快,但需要暂停所有其他的工作线程。

(2)并发标记:GC 和用户线程一起工作,执行GC Roots跟踪标记过程,不需要暂停工作线程。

(3)重新标记:在并发标记过程中用户线程继续运作,导致在垃圾回收过程中部分对象的状态发生了变化,未来确保这部分对象的状态的正确性,需要对其重新标记并暂停工作线程。

(4)并发清除:清理删除掉标记阶段判断的已经死亡的对象,这个过程用户线程和垃圾回收线程同时发生。

需要重新标记 是因为在并发的过程中待回收的对象可能会变多,或者原来被判定为垃圾的现在被强引用了。


CMS的问题 

(1)CMS收集器对处理器资源非常敏感。

(2)CMS是基于标记-清除算,产生大量的空间碎片。

(3)如果并发失败,响应时间就会变得很长。CMS并发失败 (因为碎片太多,需要整理) 就会退化为 serialold的, 响应时间就会变的很长。

使用如下命令查看当前jvm使用的垃圾回收器

"C:\Program Files\Java\jdk1.8.0_231\bin\java" -XX:+PrintFlagsFinal -version |  findstr "GC"

 

默认使用 并行的垃圾回收器 新生代老年代都是。

调优步骤

 

 在查询数据库时不要select * ,使用数据类型能用占用空间小的尽量用,实现缓存 不要自己建map,尽量使用第三方缓存,比如redis,这样和堆区没有关系。

新生代调优

 TLAB 就和ThreadLocal差不多,每一个线程在堆区(伊甸园)都有自己的一块区域供他们分配内存。这样就各自的数据就隔离了,增加并发度。

新生代比例越大越好吗

 不是的,新生代越大,minor gc 的次数越少,在一定条件下,吞吐量也越大,但随着新生代比例进一步增大,每次gc 的时间就会边长,吞吐量反而下降,大致可以认为是钟形的。

新生代能容纳所有[并发量*(请求-响应)]的数据,这样尽可能的减少或者不发生新生代gc

幸存区大到能保留[挡前活跃对象+需要晋升对象

老年代调优

待续

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

trigger333

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值