JVM 垃圾回收分配及算法

一、判断对象是否可以回收

垃圾收集器在做垃圾回收的时候,首先需要判定的就是哪些内存是需要被回收 的,哪些对象是「存活」的,是不可以被回收的;哪些对象已经「死掉」了,需 要被回收。 一般有两种方法来判断:

        引用计数器法:为每个对象创建一个引用计数,有对象引用时计数器 +1,引用被释放时计数 -1,当计数器为 0 时就可以被回收。它有一个缺点不能解决循环引用的问题

        可达性分析算法:从 GC Roots 开始向下搜索,搜索所走过的路径称为引用链。 当一个对象到 GC Roots 没有任何引用链相连时,则证明此对象是可以被回收的。

二、堆空间分配年轻代老年代及对应回收算法

堆主要用于存放各种类的实例对象和数组。在java中被分为两个区域:年轻代和老年代。 

年轻代和老年代的划分是为了更好的内存分派及回收。提高效率。堆是垃圾回收机制的重点区域。我们知道垃圾回收机制有三种,minor gc,major gc 和full gc。针对于堆的就是前两种。年轻代的叫 minor gc,老年代的叫major gc。 

1. 年轻代

年轻代中存在的对象是死亡非常快的,存在朝生夕死的情况。尺寸随堆大小的增加和减少而相应的变化,默认值是保持为堆的1/15。所以为了提高年轻代的垃圾回收效率,又将年轻代划分为三个区域: Eden区SurvivorFrom区SurvivorTo区

eden和survivor默认比例是8:1:1,进行垃圾回收采用的是分代复制算法(优点是避免内存碎片新创建的对象都会被分配到Eden区(如果该对象占用内存非常大,则直接分配到老年代区),当Eden区内存不够的时候就会触发MinorGC(Survivor满不会引发MinorGC,而是将对象移动到老年代中), 每次新生代的使用,会是eden区和一块survivor区。当我们进行垃圾回收的时候,清除正在使用的区域,将其中的存货对象,放入到另一个survivor区域并进行整理,保证空间的连续如果对象长时间存活,则将对象移动到老年区。“From”区和“To”区互换角色,原Survivor To成为下一次GC时的Survivor From区, 总之,GC后,都会保证Survivor To区是空的。存活下来的对象,他的年龄会增长1。当对象的年龄一次次存活,一次次增长,到达15的时候,这些对象就会移步到老年代。在年轻代执行gc的时候,如果老年代的连续空间小于新生代对象的总大小,就会触发一次full gc。是为了给新生代做担保,保证新生代的老年对象可以顺利的进入到老年代的内存区。

2. 老年代

随着Minor GC的持续进行,老年代中对象(年龄大于15的对象)也会持续增长,导致老年代的空间也会不够用,最终会执行Major GC(或full gc)(MajorGC 的速度比 Minor GC 慢很多很多,据说10倍左右),full gc会包含年轻代的gc。但老年代只要执行gc就一定是full gc。full gc使用的算法是:标记清除(回收)算法或标记压缩算法

标记无用对象,然后进行清除回收。 标记-清除算法(Mark-Sweep)是一种常见的基础垃圾收集算法,当进行标记清除时,会停止整个程序(stop the world),它将垃圾收集分为两个阶段:

        标记阶段:从根节点开始遍历,标记所有被引用的对象,一般在对象的header中标记为可达对象。

        清除阶段:collector对堆内存从头到尾进行线性遍历,如果发现某个对象的header没有标记为可达对象,则回收 。这里的回收是把对象的地址保存在空闲的地址列表中(内存分配),下次对象需要加载时,判断垃圾的位置空间是否够,如果够就存放覆盖原有的地址。

优点:实现简单,不需要对象进行移动。

缺点:标记、清除过程效率低,产生大量不连续的内存碎片,提高了垃圾回收的频率。 

3. 永久代(元空间)

在Java8中,永久代已经被移除,被一个称为“元数据区”(元空间,Metaspace)的区域所取代。
值得注意的是:元空间并不在虚拟机中,而是使用本地内存(之前,永久代是在jvm中)。这样,解决了以前永久代的OOM问题,元数据和class对象存在永久代中,容易出现性能问题和内存溢出,毕竟是和老年代共享堆空间。java8后,永久代升级为元空间独立后,也降低了老年代GC的复杂度。

元空间也是对java虚拟机的方法区的一种实现。元空间与永久代最大的区别在于,元空间不在虚拟机中,使用本地内存。通过配置如下参数可以更改元空间的大小。
        -XX:MetaspaceSize:初始空间的大小。达到该值就会触发垃圾收集进行类型卸载,同时GC会对该值进行调整:如果释放了大量的空间,就适当降低该值;如果释放了很少的空间,那么在不超过MaxMetaspaceSize时,适当提高该值。
        -XX:MaxMetaspaceSize,最大空间,默认是没有限制的。
永久代的回收会随着full gc进行移动,消耗性能。每种类型的垃圾回收都需要特殊处理元数据。将元数据剥离出来,简化了垃圾收集,提高了效率。

三、其他垃圾回收算法

1. 复制算法(年轻代使用)

为了解决标记-清除算法的效率不高的问题,产生了复制算法。它把内存空间划为两个相等的区域,每次只使用其中一个区域。垃圾收集时,遍历当前使用的区域,把存活对象复制到另外一个区域中,最后将当前使用的区域的可回收的对象进行回收。

优点:按顺序分配内存即可,实现简单、运行高效,不用考虑内存碎片。

缺点:可用的内存大小缩小为原来的一半,对象存活率高时会频繁进行复制。

2. 标记-整理算法(标记压缩算法

在新生代中可以使用复制算法,但是在老年代就不能选择复制算法了,因为老年代的对象存活率会较高,这样会有较多的复制操作,导致效率变低。标记-清除算法可以应用在老年代中,但是它效率不高,在内存回收后容易产生大量内存碎 片。因此就出现了一种标记-整理算法(Mark-Compact)算法,与标记-清除算法不同的是,在标记可回收的对象后将所有存活的对象压缩到内存的一端,使他们紧凑的排列在一起,然后对端边界以外的内存进行回收。回收后,已用和未用的内存都各自一边。

优点:解决了标记-清理算法存在的内存碎片问题。

缺点:仍需要进行局部对象移动,一定程度上降低了效率。

参考:

JVM年轻代,老年代,永久代详解 - 经典鸡翅 - 博客园 (cnblogs.com)

jvm之年轻代(新生代)、老年代、永久代以及GC原理详解_老年代空间多大-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/357011.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

KT148A-SOP8语音芯片接收到一线串口指令到播放声音大概多长时间

一、问题简介 请问KT148A-SOP8语音芯片接收到一线串口指令,到播放出来声音,大概需要多长时间 我的需求是做按键提示音,初测了一下感觉有延时,这个要如何处理 详细说明 KT148A从接收到指令,到执行,到播放…

非关系型数据库NoSQL数据层解决方案 之 Mongodb 简介 下载安装 springboot整合与读写操作

MongoDB 简介 MongoDB是一个开源的面向文档的NoSQL数据库,它采用了分布式文件存储的数据结构,是当前非常流行的数据库之一。 以下是MongoDB的主要特点和优势: 面向文档的存储: MongoDB是一个面向文档的数据库管理系统&#xff0…

04_FFmpeg常用API及内存模型

【说明】课程学习地址:https://ke.qq.com/course/468797 FFmpeg内存模型 FFmpeg内存模型 int avcodec_send_packet(AVCodecContext *avctx, const AVPacket *avpkt); int avcodec_receive_frame(AVCodecContext *avctx, AVFrame *frame);问题(数据的申请和释放): …

opencascade AIS_InteractiveContext源码学习1 object display management 对象显示管理

AIS_InteractiveContext 前言 交互上下文(Interactive Context)允许您在一个或多个视图器中管理交互对象的图形行为和选择。类方法使这一操作非常透明。需要记住的是,对于已经被交互上下文识别的交互对象,必须使用上下文方法进行…

在同一个 Blazor 应用中结合 SQL-DB 和 MongoDB

介绍 传统上,在单应用程序中,我们对整个应用程序使用单个数据库服务器。但是,我将 SQL 数据库和 MongoDB 结合在同一个应用程序中。此应用程序将是 RDBMS 和 No SQL 数据库的组合。我们将从头开始创建一个 Blazor 应用程序,并使用…

Node.js 渲染三维模型并导出为图片

Node.js 渲染三维模型并导出为图片 1. 前言 本文将介绍如何在 Node.js 中使用 Three.js 进行 3D 模型渲染。通过结合 gl 和 canvas 这两个主要依赖库,我们能够在服务器端实现高效的 3D 渲染。这个方法解决了在服务器端生成和处理 3D 图形的需求,使得可…

Kotlin 语言基础学习

什么是Kotlin ? Kotiln翻译为中文是:靠他灵。它是由JetBrains 这家公司开发的,JetBrains 是一家编译器软件起家的,例如常用的WebStorm、IntelliJ IDEA等软件。 Kotlin官网 JetBrains 官网 Kotlin 语言目前的现状: 目前Android 已将Kotlin 作为官方开发语言。 Spring 框…

SVN学习(002 svn冲突解决)

尚硅谷SVN高级教程(svn操作详解) 总时长 4:53:00 共72P 此文章包含第20p-第p29的内容 冲突 产生冲突的操作 (第一种 相互不影响的操作) 用户1修改第二行 用户2修改第四行 用户1提交 用户2提交,提交的时候会提示版本已过时 这时将用…

ShareX,屏幕截图、屏幕录制和文件共享,还提供了丰富的高级功能和自定义选项

ShareX是一个免费开源的Windows应用程序,用于屏幕截图、屏幕录制和文件共享。它不仅支持基本的屏幕截图功能,还提供了丰富的高级功能和自定义选项,使其成为提高工作效率和截图体验的利器。以下是ShareX v16.1.0便携版的主要功能和特色&#x…

如何跳出认知偏差,个人认知能力升级

一、教程描述 什么是认知力?认知力(cognitive ability),实际上就是指一个人的认知能力,是指人的大脑加工、储存和提取信息的能力,或者主观对非主观的事物的反映能力,如果变成大白话&#xff0c…

RIP与OSPF发布默认路由(华为)

#交换设备 RIP与OSPF发布默认路由 合理使用默认路由可以很大程度上减少本地路由表的大小,并可以较好的隐藏一个网络中的路由信息,保护自身网络的隐秘性 另外如果在同一个路由器两端使用了不同的路由协议,那么如果不做路由引入或者发布默认…

JVM 性能分析案列——使用 JProfiler 工具分析 dump.hprof 堆内存快照文件排查内存溢出问题

在 windows 环境下实现。 参考文档 一、配置 JVM 参数 配置两个 JVM 参数: -XX:HeapDumpOnOutOfMemoryError,配置这个参数,会在发生内存溢出时 dump 生成内存快照文件(xxx.hprof)-XX:HeapDumpPathF:\logs&#xff…

公共 IP 地址和私有 IP 地址的区别总结

什么是IP地址? IP 地址,即互联网协议地址(Internet Protocol Address),是网络设备在网络中进行通信的标识。IP 地址可以看作是设备在网络中的“地址”,有助于数据包在网络中找到正确的接收端。IP 地址主要…

华为---RIP路由协议的汇总

8.3 RIP路由协议的汇总 8.3.1 原理概述 当网络中路由器的路由条目非常多时,可以通过路由汇总(又称路由汇聚或路由聚合)来减少路由条目数,加快路由收敛时间和增强网络稳定性。路由汇总的原理是,同一个自然网段内的不同子网的路由在向外(其他…

UI设计速成课:理解模态窗口与非模态窗口的区别

我们日常所说的弹性框架是非常笼统的概念。我们习惯性地称之为对话框架、浮动层和提示条。弹性框架可以分为两种:模态弹性框架和非模态弹性框架。产品需要弹性框架来传递信息,用户需要弹性框架来接受反馈,但是没有经过推敲的弹出窗口设计很容易让用户感到…

链表中环的入口节点

链表中环的入口节点 描述 链表中环的入口节点 给一个长度为n链表&#xff0c;若其中包含环&#xff0c;请找出该链表的环的入口结点&#xff0c;否则&#xff0c;返回null。 数据范围&#xff1a; n≤10000&#xff0c; 1<结点值<10000 要求&#xff1a;空间复杂度 O(1)…

Android使用MPAndroidChart 绘制折线图

效果图&#xff1a; 1.导入依赖 1.1在项目根目录下的build.gradle文件中添加代码&#xff08;注意不是app下的build.gradle&#xff09;&#xff1a; maven { url https://jitpack.io } 1.2在app下的build.gradle中的依赖下添加&#xff1a; implementation com.github.PhilJa…

外部存储器

外部存储器是主存的后援设备&#xff0c;也叫做辅助存储器&#xff0c;简称外存或辅存。 它的特点是容量大、速度慢、价格低&#xff0c;可以脱机保存信息&#xff0c;属于非易失性存储器。 外存主要有&#xff1a;光盘、磁带、磁盘&#xff1b;磁盘和磁带都属于磁表面存储器…

6G时代,即将来临!

日前&#xff0c;由未来移动通信论坛、紫金山实验室主办的2024全球6G技术大会在南京召开。本次大会以“创新预见6G未来”为主题&#xff0c;在大会开幕式上发布了协力推进全球6G统一标准行动的倡议和紫金山科技城加速培育以6G技术引领未来产业行动计划。 在我国已开展第五代移动…

Python发送Email的性能怎么样?如何配置?

Python发送Email怎么配置SMTP&#xff1f;批发邮件的方法技巧&#xff1f; Python是一种广泛使用的编程语言&#xff0c;因其简洁和强大的功能深受开发者喜爱。在许多应用场景中&#xff0c;Python发送Email是一个常见需求。那么&#xff0c;Python发送Email的性能怎么样呢&am…