jvm 内存泄漏现象和处理方案

什么是内存泄漏

指程序中动态分配内存给一些临时对象,但是对象不会被GC所回收,它始终占用内存。即被分配的对象可达但已无用。

造成这种现象的原因要从,jvm内存模型和java GC机制说起
在这里插入图片描述
一般局部变量是存在java虚拟机栈的栈帧里,在代码里一个方法就会有一个栈帧, new一个对象他会在堆里开辟块内存来存放他的实例,当这个实例赋值给局部变量的时候,就把它们通过动态链接连接上了,这就是常说的栈指向堆。

当方法执行完成后,栈帧就弹出java虚拟机栈,然后销毁,但之前动态链接指向的对象实例任然会存在在堆内存里。这时就有javaGC的机制来处理这已经不用的对象了。

结构

这时说一下堆内存的结构,堆是由新生代和老年代组成,新生代里又有Eden和SurvivorFrom、SurvivorTo区。

垃圾判断算法

一般通过这两种算法去判断对象是否存活:1.引用计数法 2.可达性分析算法

分代收集算法

分代收集算法分代收集算法严格来说并不是一种思想或理论,而是融合上述3种基础的算法思想,而产生的针对不同情况所采用不同算法的一套组合拳,根据对象存活周期的不同将内存划分为几块。

新生代中,每次垃圾收集时都发现有大批对象死去,只有少量存活,那就选用复制算法,只需要付出少量存活对象的复制成本就可以完成收集。

老年代中,因为对象存活率高、没有额外空间对它进行分配担保,就必须使用标记-清理算法或者标记-整理算法来进行回收。

对象年龄

虚拟机给每个对象定义了一个对象年龄(Age)计数器,如果对象在Eden出生并经过第一次Minor GC后仍然存活,并且能被Survivor容纳的话,将被移动到Survivor空间中(正常情况下对象会不断的在Survivor的From与To区之间移动),并且对象年龄设为1。对象在Survivor区中每经历一次Minor GC,年龄就增加1岁,当它的年龄增加到一定程度(默认15岁),就将会晋升到老年代中。对象晋升老年代的年龄阈值,可以通过参数 XX:MaxPretenuringThreshold 设置。

GC流程

Minor GC
新new对象的时候会在Eden区开辟内存空间,当Eden区没有足够空间进行分配时,虚拟机会发起一次 Minor GC,此时就会把Eden+SurvivorFrom里面没有非存活的对象都回收调,把存活的对象用复制回收算法放到SurvivorTo区里面(如果From内存不足了,会直接放到老年代里),然后From Survivor和To Survivor的逻辑关系会发生颠倒: From变To , To变From,目的是保证有连续的空间存放对方,避免碎片化的发生。这样第二次Minor GC的时候就会把Eden区存活的对象放到了之前的SurvivorTo里了。

Full GC
每一次Minor GC过后,都会往新生代里的Survivor区放还存活的对象,而本身就存在在Survivor区存活的对象则会年龄+1,直到到达年龄最大限制值时(可以通过配置XX:MaxPretenuringThreshold来修改最大年龄限制,此参数默认为15),会通过复制回收算法把对象放到老年代里。当很多次这样的操作之后,老年代内存也写满了,就会触发Full GC了。

内存泄漏现象详细描述

内存泄漏现象就是,在开发时,创建完一个对象之后,这个对象在后面的代码里没有再需要用他了,但是却还被之前代码引用着无法释放,他就会先一直存放在新生代的Survivor区里,直达多次Minor GC 让这对象的年龄到达设置的最高值,最终到老年代里,而老年代里的对象是只有老年代写满后触发的Full GC才能回收资源,所以他就一直站着内存不释放,而且程序里也没有再使用他的地方,这样就是内存泄漏。

内存泄漏处理

三个方面处理
1.主要因为代码原因造成的内存泄漏,可以找机器内存里占内存比较多的类,找到用他的方法,优化代码逻辑,及时释放对象的引用。
2.jvm参数,可以通过增大XX:MaxPretenuringThreshold参数值,让对象更有可能被Minor GC回收掉,但同时得用XX:PretenureSizeThreshold这个参数限制存放在新生代的最大的对象是多少,防止对象在新生区,占用空间大,会由于空间不足而导致很多小对象进入到老年区,最后可以增大Survivor区的内存使用率-XX:TargetSurvivorRatio这个参数(默认为50%),降低进入老年代的频率。
3.机器根据程序的访问量来保证数量,还得做好负载均衡,防止某一台机器访问量过高,这样也容易造成内存泄漏,当内存泄漏严重的时候,会造成内存溢出,从服务挂掉。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值