java gc 根搜索算法_Java内存管理及GC算法

概述

内存划分

虚拟机规范中将内存分为六大部分,分别为PC寄存器、JAVA虚拟机栈、JAVA堆、方法区、运行时常量及本地方法栈。

1.PC寄存器:线程独占;

2.JAVA虚拟机栈:线程独有;JAVA虚拟机栈是在创建线程的同时创建的,用于存储栈帧,JAVA虚拟机栈也是线程独有的。

3.JAVA堆:全局共享;

4.方法区:全局共享;它主要存储的是

运行时常量池

字段信息

方法信息

构造方法

普通函数的字节码内容以及一些特殊方法。

5.本地方法栈:线程独有,本地方法栈是一个传统的栈,它用来支持native方法的执行。如果JAVA虚拟机是使用的其它语言实现指令集解释器的时候,也会用到本地方法栈。

内存管理

1.一部分是全局共享:

JAVA堆

方法区

2.一部分是线程独有

PC寄存器

JAVA虚拟机栈

本地方法栈

GC简介及算法

GC策略解决了哪些问题?

内存作为一种有限的资源,然而随着时间的推移内存的垃圾会越来越多。但java并没有提供类似于C/C++这一类内存释放和管理的机制,而是通过内置的GC进行内存的管理。GC的主要工作是:

1.哪些对象可以被回收?

2.何时回收?

3.采用什么样的方式回收?

GC策略采用的何种算法

有一种比较简单直观的办法,它的效率较高,被称作引用计数算法。但是这个算法有一个致命的缺陷,那就是对于循环引用的对象无法进行回收。

根搜索算法(解决哪些对象可以被回收的问题)

由于引用计数算法的缺陷,所以JVM一般会采用一种新的算法,叫做根搜索算法。它的处理方式就是,设立若干种根对象,当任何一个根对象到某一个对象均不可达时,则认为这个对象是可以被回收的。

GC roots(GC根),在JAVA语言中,可以当做GC roots的对象有以下几种:

虚拟机栈中的引用的对象。

方法区中的类静态属性引用的对象。

方法区中的常量引用的对象。(final)

本地方法栈中JNI的引用的对象。

第一和第四种都是指的方法的本地变量表,第二种表达的意思比较清晰,第三种主要指的是声明为final的常量值。

垃圾收集算法

垃圾搜集的算法主要有三种,分别是标记-清除算法、复制算法、标记-整理算法。这三种算法都扩充了根搜索算法。

标记-清除算法

当堆中的有效内存空间(available memory)被耗尽的时候,就会停止整个程序(也被成为stop the world),然后进行两项工作,第一项则是标记,第二项则是清除。

标记:标记的过程其实就是,遍历所有的GC Roots,然后将所有GC Roots可达的对象标记为存活的对象。

清除:清除的过程将遍历堆中所有的对象,将没有标记的对象全部清除掉。

通俗地说也就是当可用内存即将耗尽时,逐步完成以下工作:

1.GC线程就会被触发并将程序暂停;

2.将依旧存活的对象标记起来;

3.将堆中未标记的对象全部清除;

4.程序恢复运行。

缺陷:

1、首先,它的缺点就是效率比较低(递归与全堆对象遍历),而且在进行GC的时候,需要停止应用程序,这会导致用户体验非常差劲

2、第二点主要的缺点,则是这种方式清理出来的空闲内存是不连续的

复制算法

复制算法由“标记-清除算法”基础上演化而来。

复制算法将内存划分为两个区间,在任意一个时间点,所有动态分配的对象只能分配在其中一个区间(活动区间),而另一个区间(空闲区间)则是空闲的。

当可用内存即将耗尽时,会逐步完成以下工作:

1.GC线程就会被触发并将程序暂停;

2.将依旧存活的对象标记起来;

3.将存活对象全部复制到空闲区间,且严格按照内存地址依次排序;

4.将存活对象引用指向新地址;

5.将活动区间转换成空闲区间,并一次性全部回收所有垃圾对象;

6.程序恢复运行。

复制算法弥补了标记-清除算法中内存布局混乱的缺点,但其缺点也很明显:

浪费了一半的内存,也就是说有一半的内存空间是闲置的;

如果对象的存活率很高,我们可以极端一点,假设是100%存活,那么我们需要将所有对象都复制一遍,并将所有引用地址重置一遍。复制这一工作所花费的时间,在对象存活率达到一定程度时,将会变的不可忽视。

复制算法要想使用,最起码对象的存活率要非常低才行,而且最重要的是,我们必须要克服50%内存的浪费。

标记-整理算法

标记-整理算法和标记-清除算法类似,可以分成两个阶段:标记和整理

1.标记:它的第一个阶段与标记/清除算法是一模一样的,均是遍历GC Roots,然后将存活的对象标记。

2.整理:移动所有存活的对象,且按照内存地址次序依次排列,然后将末端内存地址以后的内存全部回收。因此,第二阶段才称为整理阶段。

优点:标记/整理算法不仅可以弥补标记/清除算法当中,内存区域分散的缺点,也消除了复制算法当中,内存减半的高额代价

缺点:标记/整理算法唯一的缺点就是效率也不高

复制算法、标记/整理算法、标记/清除算法共同点:

1、三个算法都基于根搜索算法去判断一个对象是否应该被回收,而支撑根搜索算法可以正常工作的理论依据,就是语法中变量作用域的相关内容。因此,要想防止内存泄露,最根本的办法就是掌握好变量作用域,而不应该使用前面内存管理杂谈一章中所提到的C/C++式内存管理方式。

2、在GC线程开启时,或者说GC过程开始时,它们都要暂停应用程序(stop the world)。

区别:

效率:复制算法>标记/整理算法>标记/清除算法(此处的效率只是简单的对比时间复杂度,实际情况不一定如此)。

内存整齐度:复制算法=标记/整理算法>标记/清除算法。

内存利用率:标记/整理算法=标记/清除算法>复制算法。

分代搜集算法

没有最好的算法,只有最合适的算法,不同算法适合不同的场景。

新生代或者年轻代【普通GC(minor GC)】:适合使用复制算法

年老代【全局GC(major GC or Full GC)】:采用标记/整理或者标记/清除算法

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值