Java GC 垃圾回收算法 内存分配

垃圾回收(Garbage Collection, GC)是Java不同于c与c++的重要特性之一。

他帮助Java自动清空堆中不再使用的对象。

由于不需要手动释放内存,程序员在编程中也可以减少犯错的机会。

利用垃圾回收,程序员可以避免一些指针和内存泄露相关的bug(这一类bug通常很隐蔽)。

垃圾回收实际上是将原本属于程序员的责任转移给计算机。

GC需要完成的3件事情:

哪些内存需要回收

什么时候回收

如何回收

1 回收那些对象?

在Java中采用可达性分析算法来判定对象是否存活,是否可以被回收。

这个算法通过一系列的被称为”GC Root”的对象作为根节点,

从他们开始向下搜索,搜索走过的路径被称为引用链(Reference Chain).

当一个对象没有一条引用链与GC Root 连接时,

即从GC Root 到这个对象是不可达的,说明这个对象是不可用的。

如图示:

object5 object6 object7 虽然互联互通

但是他们到GC Root是不可达的

所以他们将被判定为可以回收的对象

那么有一个重要的问题是 what is GC Root?

在Java语言中,可以看做是GC Root的是:

虚拟机栈中引用的变量 (可理解为方法中的局部变量)

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

方法区中的常量引用的对象

本地方法栈中的JNI(native方法)引用的对象

2 垃圾回收算法

2.1 标记-清除算法

顾名思义,该方法分为标记和清除2个过程

标记:将所有需要回收的对象区域进行标记

清除:清除所有配标记的区域里的对象

算法不足之处:

效率问题:标记和清除的效率都不高

空间问题:清除后产生的空间是不连续的碎片

无法满足后续运行中大对象的需求

2.2 复制算法

将整个空间划分2个相等的区域,每次只使用其中一个区域

当一块内存不够时,就将活着的对象复制到另一块内存

然后将第一块的内存全部回收。

这样每次对整个半区回收,就不会有内存碎片的情况,实现简单,运行高效

问题:  该算法的代价就是可以内存大小缩小为原来的一半

解决:现在商用的虚拟机都采取复制算法.

但由于所有的对象是朝生夕死的,所以并不是按照1:1的比例来划分内存的

而是将内存划分为一块较大的Eden区(new一个对象是就是在这里面分配空间)

和2块Survivor区域。每次使用Eden和一块Survivor。

当回收的时候,将Eden和Survivor区中还存活的对象一次性赋值到另一块Survivor中

最后清理掉原来使用过的Eden和Survivor区

这3个区域也被称为新生代。HotSpot的默认新生代各区域比例如下:

每次新生代中可用的空间为整个新生代的90%, 即80% Eden + 10% 1个Survivor

此时只有10% 1个Survivor 会被’浪费’

如果另一块Survivor区域存放不下Eden和Survivor区存活下来的对象

就要依靠其他区域来存放 即老年代

2.3 标记-整理算法

类似于标记-清除算法,先标记所有可以回收的区域,然后不是直接回收,

而是把所有存活的对象都移动到一端,然后直接清理掉端边界以外的区域

标记-整理算法和标记-清除算法常用于老年代的回收

老年代存放的对象存活的时间较长

而且垃圾回收的频率不如新生代的频繁

时间: 2024-10-25 15:46:36

Java GC 垃圾回收算法 内存分配的相关文章

Java的垃圾回收和内存分配策略

本文是<深入理解Java虚拟机 JVM高级特性与最佳实践>的读书笔记 在介绍Java的垃圾回收方法之前,我们先来了解一下Java虚拟机在执行Java程序的过程中把它管理的内存划分为若干个不同的的数据区的什么? 1.Java运行时数据区的划分 如下图: 其中程序计数器,虚拟机栈,本地方法栈这3个区域的内存随线程而生,随线程而灭的,因此这几个区域的内存分配与回收都是有确定的,我们不需要考虑这几个区域的内存的分配与回收.而堆和方法区则不一样,我们只有在程序处于运行期间时才能知道会创建哪些对象,这部分

【java虚拟机序列】java中的垃圾回收与内存分配策略

在[java虚拟机系列]java虚拟机系列之JVM总述中我们已经详细讲解过java中的内存模型,了解了关于JVM中内存管理的基本知识,接下来本博客将带领大家了解java中的垃圾回收与内存分配策略. 垃圾回收(Garbage Collection,GC)是java语言的一大特色,在Java中,程序员不需要去关心内存动态分配和垃圾回收的问题,这一切都交给了JVM来处理.而在C/C++中是需要程序员主动释放的,而在java中则交给JVM自动完成,既然是交给程序自动执行,那么这里就必须完成以下几件事:

Java GC - 垃圾回收机制

1.简介 对于Java developer来说,了解JVM GC工作原理能够帮助我们开发出更优秀的应用,同时在处理JVM瓶颈时能够更加自由.在最近一年的应用开发中能体会到这些知识带来的好处,并且让我们的应用在较大规模的并发时能够良好的工作. 本文部分知识和图片来源于书籍<Java Performance> - Charlie Hunt & Binu John 著,该书全面讲解了Java 应用的性能分析.优化点与JVM原理等知识,本文(以及稍候的一些文章)只包含 GC collector

面试官,不要再问我“Java GC垃圾回收机制”了

Java GC垃圾回收几乎是面试必问的JVM问题之一,本篇文章带领大家了解Java GC的底层原理,图文并茂,突破学习及面试瓶颈. 楔子-JVM内存结构补充 在上篇<JVM之内存结构详解>中有些内容我们没有讲,本篇结合垃圾回收机制来一起学习.还记得JVM中堆的结构图吗? 图中展示了堆中三个区域:Eden.From Survivor.To Survivor.从图中可以也可以看到它们的大小比例,准确来说是:8:1:1.为什么要这样设计呢,本篇文章后续会给出解答,还是根据垃圾回收的具体情况来设计的.

.NET的堆和栈04,对托管和非托管资源的垃圾回收以及内存分配

在" .NET的堆和栈01,基本概念.值类型内存分配"中,了解了"堆"和"栈"的基本概念,以及值类型的内存分配.我们知道:当执行一个方法的时候,值类型实例会在"栈"上分配内存,而引用类型实例会在"堆"上分配内存,当方法执行完毕,"栈"上的实例由操作系统自动释放,"堆"上的实例由.NET Framework的GC进行回收. 在" .NET的堆和栈02,值类型和

JAVA虚拟机垃圾回收算法原理

除了释放不再被引用的对象外,垃圾收集器还要处理堆碎块.新的对象分配了空间,不再被引用的对象被释放,所以堆内存的空闲位置介于活动的对象之间.请求分配新对象时可能不得不增大堆空间的大小,虽然可以使用的总空闲空间是足够的.这是因为,堆中没有连续的空闲空间放得下新的对象. 垃圾收集器算法 任何垃圾回收算法都必须做两件事,首先,它必须检测出垃圾对象.其次,它必须回收垃圾对象所使用的堆空间并还给程序.从根对象开始,任何可以被触及的对象都被认为是“活动的”对象(如果正在运行的程序可以访问到根对象和某个对象之间

白话说java gc垃圾回收

gc是java区别于其他好几门语言(c/c++)的一个代表功能(当然也有很多可以自动管理内存的语言,如所有的脚本语言,你根本不知道内存管理这回事)! 当然,之所以要把c/c++和java相比,是因为java出现的初衷即是对标c++的缺点的.不管怎么样,gc让程序员gg们不用痛苦地管理内存,这是好事! 回归正题,gc是什么?小白:Garbage Collect 垃圾回收(内存),是一种自动管理内存的一种机制! 下面,我们分几个问题来讨论gc的实现及原理! 一条主线(如果是你会怎么做?): 1. 什

6.GC垃圾回收算法和垃圾收集器的关系

JAVAGC垃圾回收机制和常见垃圾回收算法 推荐博客:JVM垃圾回收机制和常见垃圾回收算法 JVM的内存结构.垃圾回收算法 原文地址:https://www.cnblogs.com/2019wxw/p/11762065.html

Java 垃圾回收与内存分配策略

垃圾回收是什么? 垃圾收集GC(Garbage Collection)是Java语言的核心技术之一,垃圾收集的目的在于清除不再使用的对象.GC通过确定对象是否被活动对象引用来确定是否收集该对象.GC首先要判断该对象是否是时候可以收集.两种常用的方法是引用计数和对象引用遍历. 怎么判断一个对象是否需要收集? 引用计数(最简单古老的方法) : 指将资源(可以是对象.内存或磁盘空间等等)的被引用次数保存起来,当被引用次数变为零时就将其释放. 引用计数缺陷:引用计数无法解决循环引用问题:假设对象A,B都