JVM垃圾收集机制-内存泄漏-内存溢出

本文深入探讨JVM的垃圾回收机制,包括引用计数法、根搜索算法、标记清除法等,以及如何编写高效、健壮的Java程序的建议,如避免循环中使用try...catch、缓存短命对象、使用栈内变量等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

JVM内存模型

在这里插入图片描述

环卫工人(垃圾回收器)

如下是C语言释放内存空间的话比较复杂,容易出错,没有java开发有效率
在这里插入图片描述

如何发现垃圾?

原始方法:引用计数法
	--一个对象被赋值给一个变量时,引用计数+1;
	--持有引用的变量退出作用域时,引用计数-1.

在这里插入图片描述
但是如下比如说两个对象引用(obj1,obj2)分别引用了实例1,实例2,实例1里面的属性又引用了实例2,实例2里面的属性又引用了实例1这个时候引用计数法的缺陷就表现出来了,比如代码里的作用域都结束了但两个实例对象还在相互引用(这时这两个对象应该已经是垃圾了,但是还存在相互关系就判断不出来它是垃圾,不回收)

在这里插入图片描述

根搜索算法(GC Root)
	--栈帧里的局部变量所引用的对象;
	--方法区的静态变量和常量所引用的对象;

如下图6个对象:
对象1的根在方法区不算垃圾
对象2的根在某个栈帧里不算垃圾
对象4的根在方法栈里不算垃圾
对象6没有直接的根,但被非垃圾的对象4引用了所以它也不是垃圾
对象3被对象5引用了但对象5没有根所以都是垃圾.
在这里插入图片描述

垃圾回收也要与时俱进

标记清除法
	黑色的是垃圾对象,绿色空白内存,灰色的非垃圾对象
	比较直接是垃圾对象就腾出来
	缺点:很多碎片,没有连在一起,哪天我们要保存几G的文件就悲剧了,看起来空闲空间挺大,放一个完整文件又放不进去.

在这里插入图片描述

分段复制算法
	用一半留一半,用起来效率比较高
	需要清理时,把需要存留的对象copy到下面那一半,然后把上面全清空

在这里插入图片描述

标记整理算法
	算法比较复杂,但比较灵活,效率也比较高
	尽量不往两头放,分配对象尽量往上面放,紧挨着
	每次回收就先整理一下,空白的一边,用过的一边,把不怎么用的放前面
	不想分段算法那样严格,因为有时候可能已经用了一半多了.

在这里插入图片描述

分代收集算法
	伊甸园:西方故事里人刚出生的地方(刚new出来的对象就放着里面)
	生存区:又分From、To(分段法制法)
	From  :例如对象经历了5次回收还没被回收掉就证明它的生命周期应该比较长就把它放到From里来
	老年代:回收15次后还存在就有很大几率会一直使用移到老年代里来

在这里插入图片描述

如何编写高效,健壮的Java程序

①:尽量不要在循环中使用try...catch、new对象
②:把频繁使用的短命对象缓存起来
③:尽可能使用栈内变量(方法内局部变量)
④:不要用异常来控制代码流程
⑤:用线程池、连接池,不要自己创建
⑥:学会读Java核心API源代码
⑦:推荐一本java进阶的书《Effecitve Java》

内存泄漏与内存溢出

实例1

在这里插入图片描述
实例2
在这里插入图片描述

Java之路要走的高走得远而JVM是无法绕过的门槛。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

勤奋的树懒

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

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

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

打赏作者

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

抵扣说明:

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

余额充值