JVM笔记

一、JVM笔记

1、根可达算法(java标记是否可回收的对象),一般从四个根节点出发(线程栈变量、静态变量、常量池、JNI指针)

在这里插入图片描述

2、GC回收三种算法(根据这三种算法中和运用形成自己独有的GC)

在这里插入图片描述

​ 1)、Mark-Sweep:标记清除

​ 将标记的内存删除、是否对应的内存地址;导致形成零零碎碎的空间,以至于需要大空间对象时分配失败

在这里插入图片描述

​ 2)、Copying:拷贝

​ 分配几个大空间,根据根可达算法找出可用的数据放入到另一个大空间中,再次删除要回收的对应大空间

​ 缺点:浪费空间

在这里插入图片描述

​ 3)、Mark-Compact:标记压缩

​ 回收的时候顺带将可用的进行重排序

​ 缺点:效率低,比copy还低

在这里插入图片描述

3、堆内存逻辑分区

Java1.8默认都是把内存分为两大年代,回收一般使用分带回收机制;即分为新生代与老年代

新生代使用copying(拷贝算法),老年代使用Mark Compact(标记压缩算法)

新生代与老年代在内存比例为1:3,而新生代中eden与survivor比例是8:1:1

​ 1)、新生代使用copying(拷贝算法)

​ 新生代第一次垃圾回收(major gc)将伊甸区(eden)中存活的数据拷贝到幸存区(survivor-0)之后将eden区删除回收;

​ 第二次将伊甸区(eden)中存活的对象与(survivor-0)幸存区0中对象都拷贝到幸存区1(survivor-1)中 将对应的eden与survivor-0都回收;

​ 第三次就又将survivor-1拷贝回survivor-0中,回收eden与survivor-0区;

​ 循环上面三个步骤;当存活的对象达到回收计数阈值时将对应的对象移到老年代中

​ 2)、老年代使用Mark Compact(标记压缩算法)或者Mark Sweep(标记清除算法)结合使用

​ 当老年代达到设置的阈值时就会触发full gc

在这里插入图片描述

4、垃圾回收器总图

垃圾回收器是随着内存的不断增长而演进的

在这里插入图片描述

1)、serial 垃圾收集器是内存在几兆到几十兆时,单线程的垃圾收集器(回收时执行的流程需要停止需要等待回收完成,才能再次使用程序)

​ 即年轻代使用serial,老年代使用serial old垃圾收集器回收

2)、 Parallel Scavenge垃圾收集器是内存为几百兆到几G时,多线程垃圾收集器(回收时执行的流程需要停止需要等待回收完成,才能再次使用程序),Java1.8默认使用PS+PO的垃圾收集器组合

​ 即年轻代使用Parallel Scavenge,老年代使用Parallel Old垃圾回收器

3)、CMS垃圾收集器,当内存为几十G时(多线程并不是越多越好),引入CMS垃圾回收,即多个工作线程与多个垃圾回收线程同时工作

在这里插入图片描述

​ 工作线程与垃圾回收线程同时操作会存在误认为某对象可以进行垃圾回收,需要三色标记算法解决:

黑色标记:满足自己已经标记、已经自己指向的对象也都标记(孩子)则为黑色

灰色标记:自己标记完成,还没来得及标记指向的对象则标记为灰色

白色标记:还没有遍历到的节点

在这里插入图片描述

当上图B->D,没有扫描到,业务逻辑实现A->D产生了,则会将D当成垃圾,CMS解决方案就是将A标记为灰色,依然会漏标(不建议使用CMS

在这里插入图片描述

4)、Epsilon在jvm中不做任何垃圾处理,用于开发jvm人员调bug,以及当很大的且不需要gc的对象时可以用来标记,防止其它垃圾收集器对它进行操作
5)、G1垃圾收集器,分区算法将部分区域进行回收,回收时会将所有新生代全部回收,当新生代很大时STW很长

​ 主要为分区算法,将部分回收并发收集,压缩空闲空间不会延长GC的暂停时间,更容易预测GC暂停时间,使用于不需要很高吞吐量的场景;G1主要是物理不分代(一个个小区域),逻辑分带

在这里插入图片描述

6)、ZGC垃圾回收器

​ 使用分页算法(go lang回收算法),ZGC的核心算法为颜色指针,也是进行分区,但是不再进行新生代与老年代是分带,

在这里插入图片描述

​ 7)、Shenandoah,红帽提供开源的垃圾回收器

5、Java命令进行定位
1)、jsp 列出Java中所有进程
2)、jinfo + 进程号 列出当前进程下的相关属性
3)、jstat Java中数据跟踪信息

​ jstat -gc(参数) + 进程号 : 跟踪gc的一些信息

​ jstat -gc(参数) + 进程号 + 刷新毫秒数 :跟踪gc的一些信息以多少毫秒刷新一次

4)、jstack + 线程 查看当前进程下所有的线程调用栈信息

​ 当存在cpu内存飙升时可以使用:

​ top :查看那个进程使用cpu很高

​ top -hp + 进程号 : 查看那个线程使用cpu很高

​ 最后使用jstack 查看对应的栈信息看那个方法出现问题

5)、jmap 两大作用查看堆内存中那个对象占用的情况(不同类的对象占用内存的比重),产生堆转储文件(怀疑jvm内存有bug可以将这块内存导出来分析)

​ jmap histo + 进程号 :生成对象图

​ jmap histo + 进程号 | head 20 : 生成对象图中最大的前20个类对象所占比重

使用jmap有一个严重的问题:当将堆转存文件时,会卡死状态,直到转存成功再运行(生产环境不建议使 用)

6)、使用arthas(阿尔萨斯)工具

​ arthas阿里开源的jvm诊断工具,涵盖上面命令,主要有:

​ 1、dashboard : 仪表盘,查看那个线程占用支援比较多

​ 2、head dump: 堆转储文件

​ 3、thread :列除所有线程,看那个cpu吃线程比较多

​ thread -d : 查看是否存在死锁

​ 4、jvm : 列出java中设置的jvm参数,以及使用了哪些垃圾回收器

​ 5、jad : 反编译java代码

​ 6、redefine : 在线修改class

​ 7、trace :单机版链路追踪,分布式链路追踪使用(zipkin)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值