浅谈JVM垃圾回收有哪些常用算法

一、前言:

垃圾回收:

在未来的JDK中可能G1会为ZGC所取代

先问自己几个问题:

什么是垃圾?

  • 垃圾就是堆内存中(范指)没有任何指针指向的对象实体。不具有可达性。

为什么要回收垃圾?

  • 因为我们的内存是有限的,内存长时间不清理就会导致内存溢出,OOM;
  • 只要是程序正在跑,那么就不断生成新的对象,我们需要GC开辟新的空间分配给新的对象

我们怎么回收垃圾?

  • 依靠Java的自动内存回收机制,机制的优劣由算法决定;
  • 或者说是机制的适配度由算法和应用场景共同决定。

什么时候回收垃圾?

  • 当堆中的实体对象没有任何指针指向的时候

二、GC的标记阶段算法:

标记&清除

1、引用计数(Reference Counting):

Java已经摈弃了这种算法,因为此算法需要的额外处理过多

【优】效率高,python也在用,就像论文的引用因子一样,没有用的文章就应该多多回收,清理学术垃圾。

【缺】无法处理对象的相互“循环引用”,一旦形成了引用环,就没有办法去解决。进而造成内存泄漏

2、可达性分析⭐(根搜索、Tracing Garage Collection):

GC Roots = 起始节点集,从GC Roots开始向下搜索,连接的路径为引用链,GC Roots不可达的对象被判为不可用。

哪些是GC Roots?

  • 虚拟栈上的栈帧的局部变量表引用的对象;
  • 方法区上常量引用
  • 方法区上静态变量
  • 被同步锁修饰的对象
  • 除了堆区,和堆有联系的都是起始节点……

【优】解决了循环引用的缺点

【缺】需要遍历

三、垃圾收集算法:

标记清除算法
复制算法
标记清除整理算法

标记-清除算法:

先mark可达对象,从根节点开始进行线性遍历

【优】够平均

【缺】效率不高,GC的时候导致STW,清楚后存在内存碎片(会存在一个空闲列表)

这是最快的清除算法

复制算法

先把空间分为两个部分,把标记的对象规整地移到另一个空间中(指针碰撞的方式)

【优】高效,无需mark/sweep;没有内存碎片;

【缺】牺牲了大量的空间,”最好你们全部是垃圾!“

标记-清除-整理算法

在标记之后清除完了再进行整理,属于标记清除算法的优化版,无空闲列表

【优】无空闲列表,无内存碎片;空间开销低

【缺】时间慢,需要进行多次操作。

四、finalize&内存分析工具

finalization——免死金牌

finalize是给GC调用的

【问】回收的时候会涉及到哪些操作?会伴随着什么状态?

  • 可触及:正常状态,在GC Roots的引用链上;
  • 可复活:需要重写finalize方法才有的,“皇帝赐给你的重写finalize方法”
  • 不可触及:finalize免死金牌只能用一次,如果没有重写的finalize方法,那么就直接挂了。

MAT & GC Roots:

Memory Analyzer Tools 内存分析工具

分析dump文件:根据GC Roots去溯源,监控内存泄漏→ JProfiler

分区算法

将堆空间分成小空间是为了降低停顿时间,降低延迟

实际的使用都是复合算法。

String

final是写死的,不能继承也不能做任何修改;

Serializable修饰是跨进程

Comparable可比较的

到此这篇关于浅谈JVM垃圾回收有哪些常用算法的文章就介绍到这了,更多相关JVM垃圾回收算法内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 新手入门Jvm--Jvm垃圾回收

    目录 1. Jvm垃圾回收 2. 作用域 3. 分类 4. 垃圾回收算法 4.1 标记-复制算法 4.2 标记-清除算法 4.3 标记-整理算法 5. 垃圾收集器 5.1 Serial收集器(-XX:+UseSerialGC -XX:+UseSerialOldGC) 5.2 Parallel Scavenge收集器(-XX:+UseParallelGC(年轻代),-XX:+UseParallelOldGC(老年代)) 5.3 ParNew收集器(-XX:+UseParNewGC) 5.4 CMS

  • JVM的7种垃圾回收器(小结)

    垃圾回收算法和垃圾回收器 对于JVM的垃圾回收算法有复制算法.标记清除.标记整理. 用阳哥的话就是:这些算法只是天上飞的理念,是一种方法论,但是真正的垃圾回收还需要有落地实现,所以垃圾回收器应运而生. JVM回收的区域包括方法区和堆,jvm对于不同区域不同的特点采用分代收集算法,比如因为所有的对象都是在Eden区进行分配,并且大部分对象的存活时间都不长,都是"朝生夕死"的,每次新生代存活的对象都不多,所以新采取复制算法:而jvm默认是新生代的对象熬过15次GC才能进入老年代,所以老年代

  • JVM的垃圾回收机制详解和调优

    文章来源:matrix.org.cn 作者:ginger547 1.JVM的gc概述 gc即垃圾收集机制是指jvm用于释放那些不再使用的对象所占用的内存.java语言并不要求jvm有gc,也没有规定gc如何工作.不过常用的jvm都有gc,而且大多数gc都使用类似的算法管理内存和执行收集操作. 在充分理解了垃圾收集算法和执行过程后,才能有效的优化它的性能.有些垃圾收集专用于特殊的应用程序.比如,实时应用程序主要是为了避免垃圾收集中断,而大多数OLTP应用程序则注重整体效率.理解了应用程序的工作负荷

  • 快速理解Java垃圾回收和jvm中的stw

    Java中Stop-The-World机制简称STW,是在执行垃圾收集算法时,Java应用程序的其他所有线程都被挂起(除了垃圾收集帮助器之外).Java中一种全局暂停现象,全局停顿,所有Java代码停止,native代码可以执行,但不能与JVM交互:这些现象多半是由于gc引起. GC时的Stop the World(STW)是大家最大的敌人.但可能很多人还不清楚,除了GC,JVM下还会发生停顿现象. JVM里有一条特殊的线程--VM Threads,专门用来执行一些特殊的VM Operation

  • JVM垃圾回收算法的概念与分析

    前言 在JVM内存模型中会将堆内存划分新生代.老年代两个区域,两块区域的主要区别在于新生代存放存活时间较短的对象,老年代存放存活时间较久的对象,除了存活时间不同外,还有垃圾回收策略的不同,在JVM中中有以下回收算法: 标记清除 标记整理 复制算法 分代收集算法 有了垃圾回收算法,那JVM是如果确定对象是垃圾对象的呢?判断对象是否存活JVM也会有几套自己判断算法了: 引用记数 可达性分析 有了垃圾回收和判断对象存在这两个概念后,再来逐步分析它们. JVM是如何判断对象是否存活的? 要是让开发人员来

  • 浅谈jvm中的垃圾回收策略

    java和C#中的内存的分配和释放都是由虚拟机自动管理的,此前我已经介绍了CLR中GC的对象回收方式,是基于代的内存回收策略,其实在java中,JVM的对象回收策略也是基于分代的思想.这样做的目的就是为了提高垃圾 回收的性能,避免对堆中的所有对象进行检查时所带来的程序的响应的延迟,因为jvm执行GC时,会stop the word,即终止其它线程的运行,等回收完毕,才恢复其它线程的操作.基于分代的思想是:jvm在每一次执行垃圾收集器时,只是对一小部分内存 对象引用进行检查,这一小部分对象的生命周

  • 浅谈JVM垃圾回收之哪些对象可以被回收

    1.背景 Java语言相比于C和C++,一个最大的特点就是不需要程序员自己手动去申请和释放内存,这一切交由JVM来完成.在Java中,运行时的数据区域分为程序计数器.Java虚拟机栈.本地方法栈.方法区和堆.其中,程序计数器.虚拟机栈和本地方法栈是线程私有的,线程销毁后自动释放.垃圾回收的行为发生在堆和方法区,主要是堆,而堆中存储的主要是对象.那么自然而然地就会有这么几个问题,哪些对象可以被回收?通过什么方式回收?本文主要探讨第一个问题,以及JVM对Java中几种引用的回收策略. 2.如何判断一

  • 浅谈JVM垃圾回收有哪些常用算法

    一.前言: 垃圾回收: 在未来的JDK中可能G1会为ZGC所取代 先问自己几个问题: 什么是垃圾? 垃圾就是堆内存中(范指)没有任何指针指向的对象实体.不具有可达性. 为什么要回收垃圾? 因为我们的内存是有限的,内存长时间不清理就会导致内存溢出,OOM: 只要是程序正在跑,那么就不断生成新的对象,我们需要GC开辟新的空间分配给新的对象. 我们怎么回收垃圾? 依靠Java的自动内存回收机制,机制的优劣由算法决定: 或者说是机制的适配度由算法和应用场景共同决定. 什么时候回收垃圾? 当堆中的实体对象

  • 浅谈Java垃圾回收的实现过程

    本教程是为了理解基本的Java垃圾回收以及它是如何工作的.这是垃圾回收教程系列的第二部分.希望你已经读过了第一部分:<简单介绍Java垃圾回收机制>. Java垃圾回收是一项自动化的过程,用来管理程序所使用的运行时内存.通过这一自动化过程,JVM解除了程序员在程序中分配和释放内存资源的开销. 启动Java垃圾回收 作为一个自动的过程,程序员不需要在代码中显示地启动垃圾回收过程.System.gc()和Runtime.gc()用来请求JVM启动垃圾回收. 虽然这个请求机制提供给程序员一个启动GC

  • 浅谈Java垃圾回收机制

    一.什么是垃圾 java中,什么样的对象是垃圾?有人说:没有被引用的对象就是垃圾对象.我一开始对此也是深信不疑的,但是当年我这么回答面试官的时候,得到的是一个大大的白眼. 判断一个对象是否是垃圾,有两种算法,一种是引用计数法,但是,这种方法解决不了循环引用的问题. /**循环问题*/ public class Demo{ public Demo instance; public static void main(String[] args) { Demo a=new Demo(); Demo b

  • 浅谈JVM内存溢出原因和解决思路

    目录 栈溢出(虚拟机栈和本地方法栈) 产生原因 解决思路 堆溢出 产生原因 解决思路 方法区和运行时常量池溢出 产生原因 解决思路 本机直接内存溢出 产生原因 解决思路 栈溢出(虚拟机栈和本地方法栈) 产生原因 在HotSpot中,只能由-Xss参数来设定.因为在HotSpot中不区分虚拟机栈和本地方法栈的. 栈溢出时会出现两种异常:StackOverflowError异常和OutOfMemoryError异常. StackOverflowError异常因为线程请求的栈深度大于虚拟机允许的最大深

  • 浅谈JVM中的JOL

    JOL简介 JOL的全称是Java Object Layout.是一个用来分析JVM中Object布局的小工具.包括Object在内存中的占用情况,实例对象的引用情况等等. JOL可以在代码中使用,也可以独立的以命令行中运行.命令行的我这里就不具体介绍了,今天主要讲解怎么在代码中使用JOL. 使用JOL需要添加maven依赖: <dependency> <groupId>org.openjdk.jol</groupId> <artifactId>jol-co

  • 浅谈JVM之使用JFR解决内存泄露

    简介 虽然java有自动化的GC,但是还会有内存泄露的情况.当然java中的内存泄露跟C++中的泄露不同. 在C++中所有被分配的内存对象都需要要程序员手动释放.但是在java中并不需要这个过程,一切都是由GC来自动完成的.那么是不是java中就没有内存泄露了呢? 要回答这个问题我们首先需要界定一下什么是内存泄露.如果说有时候我们不再使用的对象却不能被GC释放的话,那么就可以说发生了内存泄露. 一个内存泄露的例子 我们举一个内存泄露的例子,先定义一个大对象: public class KeyOb

  • jvm垃圾回收之GC调优工具分析详解

    进行GC性能调优时, 需要明确了解, 当前的GC行为对系统和用户有多大的影响.有多种监控GC的工具和方法, 本章将逐一介绍常用的工具. JVM 在程序执行的过程中, 提供了GC行为的原生数据.那么, 我们就可以利用这些原生数据来生成各种报告.原生数据(raw data) 包括: 各个内存池的当前使用情况, 各个内存池的总容量, 每次GC暂停的持续时间, GC暂停在各个阶段的持续时间. 可以通过这些数据算出各种指标, 例如: 程序的内存分配率, 提升率等等.本章主要介绍如何获取原生数据. 后续的章

  • jvm垃圾回收算法详细解析

    目录 前言 几种常用的垃圾回收算法 1.引用计数法 2.根搜索算法 3.标记清除法(Mark-Sweep) 4.复制交换算法(Mark-Sweep) 5.标记压缩算法(Mark-Compact) JVM 分代收集算法 前言 相比C语言,JVM虚拟机一个优势体现在对对象的垃圾回收上,JVM有一套完整的垃圾回收算法,可以对程序运行时产生的垃圾对象进行及时的回收,以便释放JVM相应区域的内存空间,确保程序稳定高效的运行,但在真正了解垃圾回收算法之前,有必要对JVM的对象的引用做一个简单的铺垫 JVM对

随机推荐