Java学习----JVM学习
JVM 学习
如何判断一个对象是否是垃圾
-
引用计数法
如果有一个对象指向这个对象计数
+1 取消一个引用对象技术
-1 若减为
0 则回收无法解决循环引用
-
根可达算法
(JVM 使用的方法) main 函数启动的时候会产生一个GC Root 每个对象若可达root 则不是垃圾,否则将被是为垃圾Root 包括:- JVM stack
- native method stack
- runtime constant pool
- static references in method area
- Clazz
JVM 垃圾回收算法
-
Mark-Sweep( 标记清除) 将垃圾标记后清除(会有许多碎片化的内存区域)
-
copying(拷贝)
有两个内存区域,将一个区域有用的对象拷贝到另个区域(消耗内存)
-
Mark-Compact( 标记压缩) 将碎片整理好(消耗
CPU )
JVM 垃圾回收器
分代:
分代模型分为新生代,老年代
绝大多数对象在新生代回收掉
新生代
-
8: eden
-
1:survivor *2
这两个区域会不停的复制,每复制一次都会进行将对象的年龄放入老年代
若这两个区域满了会将对象直接放入老年代
老年代
- tenured
若对象放入不了
在
之后就在
在这之中被回收对象在
打印所有可调参数: java -XX:+PringCommandLineFlags
分代回收器:
- Young:
Serial
ParNew
Parallel Scavencge
- Old:
CMS
Serial Old
Parallel Old
不分代回收器:
G1
ZGC
垃圾回收
Serial: 每过一段时间所有线程停止
Parallel Scavencge:根
ParNew:它根
并发标记
在
并发标记法(三色标记法)
白色:未被标记的对象
灰色:自身被标记,成员变量没被标记
黑色:自生被标记,成员变量均被标记
错标产生情况
假如
A 指向B ,B 指向C [A->B->C] A(黑色) 自己已经被标记,成员变量也标记完了。
B(灰色) 自己被标记完了,
C 没被标记C(白色) 没有被标记
这时候
B->C 消失变为A->C 这时候垃圾回收器会将
C 给回收。
错标解决办法
将
A 重新标记为灰色,垃圾回收器重新进行标记,这时是又STW 的
漏标产生情况
当第二个属性标完后,整体为黑色,但是
G1
与
之后
JVM 线上问题解决
jps
列出
jinfo
jstak 进程号
这个命令可以用来定位死锁
jstat -gc 进程号
统计
jmap -histo 进程号
定位哪些对象在吃内存 注意,这个命令会引起系统卡顿(线上不能用)
jmap -dump:format=b,file=xxx.hprof 进程号
将堆存成一个文件
之后我们可以使用一些工具来分析这些堆内存,例如:
- mat
- jprofiler
- jhat
- jvisualvm
jvm 自带图形化工具
- jvisualvm
- jconsole
arthas
阿里开源的工具
arthas
dashboard
用字符界面模拟的图形界面jvm
把jvm 的所有信息输出thread
把所有线程所列出来thread -b
查看死锁heapdump
相当于jmap jad 类名
将java 源码反编译redefine class路径
将文件热更新到线上去
排查
-
jvm 突然升高- 使用
arthas 查看CPU 占用最高的线程 - 若是业务线程则表示有大量计算操作
- 若是
JVM 线程则表示有频繁的FGC
- 使用
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· 因为Apifox不支持离线,我果断选择了Apipost!