微服务架构-JVM参数调优-070:jvm内存溢出+调优实战

1 怎样的对象会进入到老年代

课程内容:
1.什么时候会发生full gc
2.死锁问题怎么去定位
3.服务器cpu100%如何定位
4.内存溢出如何去寻找问题
5.jvm调优实际案例分析
在这里插入图片描述
什么样的对象进入老年代?

  1. 大对象;
  2. 长期存活的对象(默认年龄超过15次、可配置);
  3. 空间担保 对象太多minor gc s0区、s1区放不下
  4. 动态年龄 当前Survivor区对应对象年龄有50%>Survivor平均年龄,将大于的部分对象转入老年区

指定创建的对象超过多少会直接创建在老年代
此参数只能在serial收集器和parnew收集器才有效
-XX:PretenureSizeThreshold
(比如 -XX:PretenureSizeThreshold=1M)
指定多大年龄的对象进入老年代
-XX:MaxTenuringThreshold
(比如 -XX:MaxTenuringThreshold=15 默认也是15次)

2 怎么去定位死锁代码

@RestController
public class GCController {

    @Value("${mayikt.name}")
    private String name;

    private List<byte[]> bytes = new ArrayList<>();


    @GetMapping("/getName")
    public String getName() {
        byte[] bytes1 = new byte[1024 * 1024 * 4];
        return name;
    }

    @GetMapping("/deadlock")
    public String dieLock() {
        new Thread(() -> {
            synchronized (Integer.class) {
                try {
                    TimeUnit.SECONDS.sleep(1);
                    synchronized (String.class) {
                        System.out.println("执行成功");
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
        synchronized (String.class) {
            try {
                TimeUnit.SECONDS.sleep(1);
                synchronized (Integer.class) {
                    System.out.println("执行成功");
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return "死锁";
    }

    @GetMapping("/oom")
    public String cms() {
        List<byte[]> bytes = new ArrayList<>();

        while (true) {
            byte[] bytes1 = new byte[1024 * 1024 * 4];
            bytes.add(bytes1);
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    @GetMapping("/loop")
    public String loop() {
        boolean b = true;
        while (b) {
        }
        return "123";
    }

    @GetMapping("/memoryLeak")
    public String oom() {

        while (true) {
            byte[] bytes1 = new byte[1024 * 1024 * 4];
            bytes.add(bytes1);
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

}

本地使用VisualVm查看死锁
在这里插入图片描述
定位死锁
控制台输入jsp命令,查看所有java项目pid
jstack pid 打出当前运行的所有线程的快照
在这里插入图片描述
死锁只是该线程阻塞,不影响其他线程使用,但是如果死锁的代码一直有请求,最终还是会导致整个服务无法使用(线程池数量有限制)。
在这里插入图片描述

3 CPU100%怎么去定位

cpu 100% 定位思路
1.定位到哪一个程序cpu占用率高 top
2.定位到当前程序 是哪一个线程占用率高 ps -mp pid -o THREAD,tid,time,
找到对应tid
3.jstack定位到对应线程快照,打印出的日志搜索tid(转换成16进制)
在这里插入图片描述

4 堆内存溢出怎么定位

oom 异常分两种情况
1.内存溢出
2.内存泄漏

内存溢出时候打印堆内存快照
-XX:+HeapDumpOnOutOfMemoryError该配置会把快照保存在用户目录或者tomcat目录下,也可以通过 -XX:HeapDumpPath=/tmp/heapdump.dump来显示指定路径。
Configuration中VM options输入:
-Xloggc:D:\logs\gc.log -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=D:\heapdump.dump

内存溢出怎么定位:
1.程序里面有大对象;
2.大对象被谁引用,使用visualVM装入dump快照,根据线程快照找到在哪一行出现溢出。
在这里插入图片描述
内存泄漏定位:
在这里插入图片描述

5 jvm调优案例分析

参考文章:《从实际案例聊聊Java应用的GC优化》
作者:录录 美团技术团队 2017-12-28
链接:从实际案例聊聊Java应用的GC优化.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值