java中垃圾回收算法讲解
判断对象是否存活的方法:
一、引用计数算法(Reference Counting)
介绍:给对象添加一个引用计数器,每当一个地方引用它时,数据器加1;当引用失效时,计数器减1;计数器为0的即可被回收。
优点:实现简单,判断效率高
缺点:很难解决对象之间的相互循环引用(objA.instance = objB; objB.instance = objA)的问题,所以java语言并没有选用引用计数法管理内存
二、根搜索算法(GC Root Tracing)
Java和C#都是使用根搜索算法来判断对象是否存活。通过一系列的名为“GC Root”的对象作为起始点,从这些节点开始向下搜索,搜索所有走过的路径称为引用链(Reference Chain),当一个对象到GC Root没有任何引用链相连时(用图论来说就是GC Root到这个对象不可达时),证明该对象是可以被回收的。
在Java中哪些对象可以成为GC Root?
虚拟机栈(栈帧中的本地变量表)中的引用对象
方法区中的类静态属性引用的对象
方法区中的常量引用对象
本地方法栈中JNI(即Native方法)的引用对象
一、标记-清除算法(Mark-Sweep)
这是垃圾收集算法中最基础的,根据名字就可以知道,它的思想就是标记那些要被回收的对象,然后统一回收。这种方法很简单,但是会有两个主要问题:
1.效率不高,标记和清除的效率都很低;
2.会产生大量不连续的内存碎片,导致以后程序在分配交大的对象时,由于没有充足的连续内存而提前触发一次GC动作。
二、复制算法(Copying)
为了解决效率问题,复制算法将可用内存按容量划分相等的两部分,然后每次只使用其中的一块,当第一块内存用完时,就将还存活的对象复制到第二块内存上,然后一次性清除完第一块内存,在将第二块上的对象复制到第一块。但是这种方式,内存的代价太高,每次基本上都要浪费一块内存。
于是将该算法进行了改进,内存区域不再是按照1:1去划分,而是将内存划分为8:1:1三部分,较大的那份内存叫Eden区,其余两块较小的内存叫Survior区。每次都会先使用Eden区,若Eden区满,就将对象赋值到第二块内存上,然后清除Eden区,如果此时存活的对象太多,以至于Survivor不够时,会将这些对象通过分配担保机制赋值到老年代中。(java堆又分为新生代和老年代)。
三、标记-整理算法(Mark-Compact)
该算法是为了解决标记-清楚,产生大量内存碎片的问题;当对象存活率较高时,也解决了复制算法的效率问题。它的不同之处就是在清除对象的时候现将可回收的对象移动一端,然后清除掉端边界以外的对象,这样就不会产生内存碎片。
四、分代收集算法(Generational Collection)
根据对象的存活周期的不同将内存划分为几块,一般就分为新生代和老年代,根据各个年代的特点采用不同的收集算法。新生代(少量存活)用复制算法,老年代(对象存活率高)“标记-清理”算法
补充:分代划分内存介绍
整个JVM内存总共划分为三代:年轻代(Young Generation)、年老代(Old Generation)、持久代(Permanent Generation)
1、年轻代:所有新生成的对象首先都放在年轻代内存中。年轻代的目标就是尽可能快速的手机掉那些生命周期短的对象。年轻代内存分为一块较大的Eden空间和两块较小的Survior空间,每次使用Eden和其中的一块Survior.当回收时,将Eden和Survior中还存活的对象一次性拷贝到另外一块Survior空间上,最后清理Eden和刚才用过的Survior空间。
2、年老代:在年轻代经历了N次GC后,仍然存活的对象,就会被放在老年代中。因此可以认为老年代存放的都是一些生命周期较长的对象。
3、持久代:基本固定不变,用于存放静态文件,例如Java类和方法。持久代对GC没有显著的影响。持久代可以通过-XX:MaxPermSize=进行设置。
java中垃圾回收算法讲解的更多相关文章
- java面试一日一题:java中垃圾回收算法有哪些
问题:请讲下在java中有哪些垃圾回收算法 分析:该问题主要考察对java中垃圾回收的算法以及使用场景 回答要点: 主要从以下几点去考虑, 1.GC回收算法有哪些 2.每种算法的使用场景 3.基于垃圾 ...
- JAVA虚拟机垃圾回收算法原理
除了释放不再被引用的对象外,垃圾收集器还要处理堆碎块.新的对象分配了空间,不再被引用的对象被释放,所以堆内存的空闲位置介于活动的对象之间.请求分配新对象时可能不得不增大堆空间的大小,虽然可以使用的总空 ...
- 了解java中垃圾回收机制
Java的垃圾回收机制是Java环境自带有的,它不像c语言的malloc申请空间后需要Free()函数来释放,而Java中的代码块中所申请的空间可在程序执行完成后自动释放,但是是有局限性的,代码块所占 ...
- 了解java虚拟机—垃圾回收算法(5)
引用计数器法(Reference Counting) 引用计数器的实现很简单,对于一个对象A,只要有任何一个对象引用了A,则A的引用计数器就加1,当引用失效时,引用计数器减1.只要对象A的引用计数器的 ...
- 【转】Java学习---垃圾回收算法与 JVM 垃圾回收器综述
[原文]https://www.toutiao.com/i6593931841462338062/ 垃圾回收算法与 JVM 垃圾回收器综述 我们常说的垃圾回收算法可以分为两部分:对象的查找算法与真正的 ...
- Java GC 垃圾回收算法 内存分配
垃圾回收(Garbage Collection, GC)是Java不同于c与c++的重要特性之一. 他帮助Java自动清空堆中不再使用的对象. 由于不需要手动释放内存,程序员在编程中也可以减少犯错的机 ...
- java虚拟机-垃圾回收算法
在Java中,程序员不需要去关心内存动态分配和垃圾回收的问题,这一切都交给了JVM来处理.但是首先需要明确,什么样的对象才能当为垃圾: 1.引用计数法:如果某个引用(即指针)指向对象,那么说明该对象还 ...
- JVM中垃圾回收算法
GC 算法与种类 GC的概念 Garbage Collection 垃圾收集1960年 List 使用了GCJava中,GC的对象是堆空间和永久区 引用计数法 老牌垃圾回收算法通过引用计算来回收垃圾使 ...
- 浅谈PHP5中垃圾回收算法
原文链接:http://www.cnblogs.com/leoo2sk/archive/2011/02/27/php-gc.html PHP是一门托管型语言,在PHP编程中程序员不需要手工处理内存资源 ...
随机推荐
- c# 类的知识
在英语中类(class)是分类(classification)的根词.设计类的过程就是对信息进行分类,将相关信息放到有意义的实体中. 封装的目的: 封装就是定义类的重要原则.中心思想是:使用类的程序不 ...
- 使用commons-compress解压GBK格式winzip文件到UTF8,以及错误使用ZipArchiveInputStream读出来数据全是空的解决办法
先上正确方法: 正确方式应该为,先创建一个ZipFile,然后对其entries做遍历,每一个entry其实就是一个文件或者文件夹,检测到文件夹的时候创建文件夹,其他情况创建文件,其中使用zipFil ...
- nextjs 服务端渲染请求参数
Post.getInitialProps = async function (context) { const { id } = context.query const res = await fet ...
- source from Other`s
以下链接转自其他努力的程序员们: 一一感谢! http完美讲解 -- https://www.cnblogs.com/ranyonsue/p/5984001.html http协议与soap协议之间的 ...
- JustOj 1974: 简单的事情 (组合数)
题目描述 数学天才fans曾经说过一句话:组合数的计算是一件非常简单的事情.组合数的计算真的是一件非常简单的事情吗?请你自己去尝试一下吧! 输入 输入中的一些整数对n,m(m≤n≤20) 输出 输出其 ...
- vue editorConfig
在文件目录下, indent_size = 2设置为4
- 报文、http、https的理解
一.何为报文? 报文是网络中交换与传输的数据单位,即站点一次性要发送的数据块.报文包含了将要发送的完整的数据信息,其长短不一致,长度不限且可变. 二.报文的作用 报文多是多个系统之间需 ...
- Oracle初级第一天
oracle卸载 运行regedit,删除HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\ ...
- 关于Eclipse新建Dynamic Web Projecj默认未创建web.xml的问题
当使用eclipse新建Dynamic Web Projecj时,由于J2EE技术规范的更新,当使用Dynamic web module version默认版本为3.0时,将默认不会创建web.xml ...
- PyCharm配置MySQL
有时候电脑没有安装Navicat,也想要操作数据库,那么PyCharm也能实现Navicat的一些功能.下面演示,用PyCharm如何连接数据库并执行操作: 1. 打开PyCharm,在右侧边栏打开D ...