JVM堆内存模型及垃圾回收机制相关简析

JVM堆内存模型及垃圾回收机制相关简析
一、简介
​ 垃圾回收机制是Java中最重要的保障,而谈到垃圾回收,可以简单的概括为两个问题:

​ 一、在哪里回收?

​ 二、怎么回收?

​ 而对于上面两个问题结合下面我要讲的,这样回答:

​ 一、主要在堆内存模型中回收

​ 二、先判断,后回收

​ 这样可以总结为一句话,在内存模型中先进行判断流程,在进行回收流程,下面在详细解释。

二、堆内存模型
​ Java1.8之前堆内存逻辑上分为3部分,新生代、老年代、永久区。

​ 新生代又被分为一个伊甸园和两个幸存者区。

​ 并且从Java1.8开始,永久代替换为元空间。

新生代:刚创建的对象存放在伊甸园,每次GC都会将伊甸园的对象转移至幸存区

老年区:幸存区的对象经过15次GC不死就会来到老年代,而当老年区的可用内存小于新生代的可用内存就会触发一次重回收

元空间:jdk8之前为永久代,占用JVM内存,8之后为元空间,要说明的的是,元空间并不是堆的一部分,而是脱胎于方法区,他并不是不会被GC,只是GC的条件比较苛刻。

默认情况下,JVM内存 = 新生代 + 老年代(其他如栈等可忽略不计),为电脑内存的四分之一,初始化内存是六十四分之一。

三、垃圾回收
1、判断阶段
1)引用计数法
当有一个地方引用他时,对象的计数器+1,引用失效就-1,当计数器为0,就表示可以被回收。

主流Java虚拟机不采用它,无法解决对象之间循环依赖问题。

​ 引用分类:

​ 强引用:引用还在,就不会被回收

​ 软引用:发生内存溢出之前,进行回收

​ 弱引用:只能活到下一次垃圾回收之前

​ 虚引用:无法通过虚引用获得对象实例,设置虚引用的唯一目的是对象被回收时能获得一个系统通知

2)可达性分析法
通过一系列被称为 GC Roots 的对象作为起始点,从起始点开始向下搜索,当一个对象到起始点没有任何链相连,证明此对象不可用,即被回收。(按图的说法即为不可达)

3)finalization机制(不推荐)
finalize() 方法,当一个对象被可达性分析中被判断为不可达,那么会被JVM判断是否有必要执行finalize()方法(是否执行过),如果没必要执行,直接死,如果有必要执行,对象被放入F-Queue队列中,在下一次GC标记队列前,没有与起始节点想办法建立连接,则必死无疑。

2、回收阶段
1)标记清除算法
先标记后回收,最基础的回收算法,会产生内存碎片,导致内存泄漏

2)复制算法
两个幸存区的互相复制,来解决内存碎片问题

3)标记整理算法
多用于老年代,让幸存对象向一段移动,然后清理掉到端外的对象

4)分代收集算法
目前所有GC都采用分代收集算法进行回收,新生代用复制,老年代用标记整理。

5)增量收集算法
基于GC时所有应用程序的线程都会挂起,所以当GC时间过长,会造成系统长时间停顿,因此,每次GC,只收集一小部分内存的垃圾,然后切换回应用程序线程,及能一次完成的工作,分多次完成,增加了工作量,减少了系统的停顿时间,但是频繁线程切换、上下文转换,导致垃圾回收总成本上升。

6)分区算法
还是为了解决回收停顿过长的问题,将堆内存分为一个个独立使用、独立回收的小空间,从而减少一次GC所停顿的时间,并且可以控制一次回收多少个小空间。

四、相关问题
1、内存泄漏
已分配的内存由于某种情况未释放或无法释放,导致系统运行变慢甚至崩溃

2、内存溢出
即一次性从数据库读取的数据太多,超过了内存的容量,通俗说就是任何导致内存超出的情况

五、垃圾回收器
评价一个垃圾回收器的性能指标:

吞吐量
停顿时间
内存占用
收集频率
收集开销
速度

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值