JAVA 学习 面试(四)垃圾回收篇

Java中的每个对象都经历了创建、使用和最终被回收的过程。从对象实例化开始,它可能被程序的多个部分引用,直到最后一个引用消失,对象成为垃圾,等待回收。

JVM垃圾查找算法

(1)引用计数法:已淘汰,为每个对象添加引用计数器,引用为0时判定可以回收,会有两个对象相互引用无法回收的问题
(2)可达性分析法:从GCRoot开始往下搜索,搜索过的路径称为引用链,若一个对象GCRoot没有任何的引用链,则判定可以回收(三色法:未标记、标记中、已标记)

可以作为GC Roots的主要有四种对象:虚拟机栈(栈帧中的本地变量表)中引用的对象方法区中类静态属性引用的对象方法区中常量引用的对象本地方法栈中JNI引用的对象
JVM的垃圾回收算法

(1)标记清除算法: 标记不需要回收的对象,然后清除没有标记的对象,会造成许多内存碎片。

在这里插入图片描述

(2)复制算法: 将内存分为两块,只使用一块,进行垃圾回收时,先将存活的对象复制到另一块区域,然后清空之前的区域。用在新生代

优点:解决碎片化问题,顺序分配内存简单高效
缺点:只适用于存活率低的场景,如果极端情况下如果对象面上的对象全部存活,就要浪费一半的存储空间。

在这里插入图片描述

(3)标记整理算法: 与标记清除算法类似,但是在标记之后,将存活对象向一端移动,然后清除边界外的垃圾对象。用在老年代

在这里插入图片描述

(4)分代收集算法:一般将 java 堆分为新生代和老年代,比如在新生代中,选择复制算法,只需要付出少量对象的复制成本就可以完成每次垃圾收集。而老年代的对象存活几率是比较高的,选择“标记-清除”或“标记-整理”算法进行垃圾收集。

分代回收机制
  • 在年轻代,对象的存活率相对较低,因此采用如标记-复制算法会更为高效。
  • 老年代中的对象已经证明了自己的存活能力,所以此处的GC会比年轻代更加稀少,可以使用如标记-清除-整理算法进行处理。

图片

  • 年轻代主要分为Edan区、Survivor区(from/S1区、to/S2区),这三者的区域大小划分比例为8:1:1
  • 年轻代中对象被GC清理在S1与S2轮转15次之后会被移到老年代(这个值可以通过JVM参数:–XX:SurvivorRatio 设定,默认值为8)
  • 年轻代与老年代区域大小划分比例为1:2(该值可以通过JVM参数:-XX:NewRatio 设定)
当GC确定一些对象为“不可达”时,GC就有责任回收这些内存空间。可以。程序员可以手动执行System.gc(),通知GC运行,但是Java语言规范并不保证GC一定会执行。## 第一步:
大对象直接进入老年代
长期存活对象将进入老年代1. Eden 区
Java 新对象的出生地(如果新创建的对象占用内存很大,则直接分配到老年代)。当 Eden 区内存不够的时候就会触发 MinorGC,对新生代区进行一次垃圾回收。
2. ServivorFrom
上一次 GC 的幸存者,作为这一次 GC 的被扫描者。
3. ServivorTo
保留了一次 MinorGC 过程中的幸存者。

3ff6f9cc5dc34c3ca68b3585212174e2

## 第二步:
老年代的对象比较稳定,所以 MajorGC 不会频繁执行。当无法找到足够大的连续空间分配给新创建的较大对象时也会提前触发一次 MajorGC 进行垃圾回收腾出空间。
MajorGC 采用标记清除算法:
首先扫描一次所有老年代,标记出存活的对象,然后回收没有标记的对象。MajorGC的耗时比较长,因为要扫描再回收。MajorGC 会产生内存碎片,为了减少内存损耗,我们一般需要进行合并或者标记出来方便下次直接分配。## 第三步:
当老年代也满了装不下的时候,就会抛出 OOM(Out of Memory)异常.永久代:主要存放 Class 和 Meta(元数据)的信息,Class 在被加载的时候被放入永久区域,它和和存放实例的区域不同,GC 不会在主程序运行期对永久区域进行清理。所以这也导致了永久代的区域会随着加载的 Class 的增多而胀满,最终抛出 OOM 异常。
强引用、软引用、弱引用、虚引用?

在 Java 中,Reference 类及其子类是用于实现引用对象的基类。Reference 类主要有三个子类:SoftReferenceWeakReference、和 PhantomReference,它们分别代表软引用、弱引用和虚引用。

无标题.png

  1. 强引用:是我们经常写的普通对象引用,把一个对象赋给一个引用变量(在 C/C++ 中的名词称为指针变量),这个引用变量就是一个强引用。当一个对象被强引用变量引用时,它处于可达状态,它是不可能被垃圾回收机制回收的,因此强引用是造成 Java 内存泄漏的主要原因之一。
  2. 软引用:``软引用通常用在对内存敏感的程序中,比如高速缓存就有用到软引用,内存够用的时候就保留,不够用就回收
  3. 弱引用:当一个对象只被弱引用引用时,在下一次垃圾回收(GC)时,即使内存空间足够,也会被回收
  4. 虚引用:形同虚设,虚引用并不会决定对象的生命周期,作用是跟踪对象被垃圾回收的状态以及引用对象被放入与之关联的引用队列中,允许程序员在适当的时机进行一些额外的操作
finalize()方法?

垃圾回收器(garbage colector)决定回收某对象时,就会运行该对象的finalize()方法:

  • 第一次被标记后,对象在在finalize()中成功拯救自己,只要重新与引用链上的任何一个对象建立关联即可
  • 回收特殊渠道申请的内存,一般内存不需要亲自回收,但JNI(Java Native Interface)调用non-Java程序(C或C++)产生的无法被gc自动回收。
收集器种类
  • Serial收集器: 新生代采用复制算法,老年代采用标记-整理算法。单线程,所以在发生GC时候需要暂停所有线程的工作(“Stop-The-World”)。
  • Parallel Scavenge收集器:(相比Serial GC只是垃圾回收线程变多而已)适用于吞吐量比较高的场景,一些计算场景并不在意停顿时间的长短,还存在STW现象(“Stop-The-World”)
  • ParNew收集器:(jdk8默认设置的垃圾收集器)新生代采用复制算法,老年代采用标记-整理算法。和Parallel 相似主要用于配合CMS收集器使用。
  • CMS收集器:低延迟并发型垃圾收集器。适用于希望减少暂停时间的应用。(用户和垃圾回收线程可以同时工作,当然还需要少量的STW用于清除浮动垃圾),采用“标记-清除”算法,是老年代的垃圾收集器,只能配合ParNew或Serial使用。没有整理过程,会导致内存碎片化
  • G1 GC:从JDK9开始,它作为默认的垃圾回收器。它将堆分为多个区域(Reigon)并发地标记、复制和清除这些区域。限制垃圾回收的暂停时间,并提供高吞吐量。
  • ZGC:ZGC的目标是在任何堆大小下都能实现不到10毫秒的暂停时间,同时还能提供与其他垃圾回收器相似的吞吐量。
## 如何选择:
**响应时间要求**:如果应用对延迟非常敏感,那么选择如ZGC或CMS这样的暂停时间短的垃圾回收器会更合适。
**吞吐量要求**:高吞吐量的应用,如批处理作业或某些后端任务,可能更适合使用Parallel GC或G1 GC。
**内存资源**:如果内存资源有限,Serial GC可能是一个好选择。
监控垃圾回收

GC日志: JVM可以配置为输出GC日志,这些日志详细记录了垃圾回收的过程和结果。通过分析这些日志,开发者可以获取关于内存使用情况、垃圾收集的频率和持续时间等重要信息。

监控工具: 工具如JVisualVM和JConsole不仅可以实时显示JVM的性能指标,还提供了丰富的图形界面,帮助开发者直观地了解垃圾回收的行为。

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

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

相关文章

(十一)Head first design patterns状态模式(c++)

状态模式 如何去描述状态机? 假设你需要实例化一台电梯,并模仿出电梯的四个状态:开启、关闭、运行、停止。也许你会这么写 class ILift{ public:virtual void open(){}virtual void close(){}virtual void run(){}virtual void stop(){} }…

为什么电脑降价了?

周末,非常意外地用不到3000元买到了一款2023年度发布的华为笔记本I5,16G,500G,基本是主流配置,我非常意外,看了又看,不是什么Hwawii,或者Huuawe。然后也不是二手。为什么呢?因为在ALU和FPU之外&…

Java和Redis实现一个简单的热搜功能

1. 前言 我们有一个简单的需求: 搜索栏展示当前登陆的个人用户的搜索历史记录,删除个人历史记录。用户在搜索栏输入某字符,则将该字符记录下来 以zset格式存储的redis中,记录该字符被搜索的个数以及当前的时间戳 (用…

Qt Linux安装qt5.9全过程

1 准备好安装包 qt安装包下载官网:https://download.qt.io/archive/qt 2 将安装包放到Linux环境下 我这里使用WinSCP将windows下的文件传输到Linux 3 ./qt-opensource-linux-x64-5.9.0.run 3-0 运行时目录的所有权错误wrong ownership on runtime directory 解决:切换roo…

K8S的helm

helm的作用 在没有helm之前,deploymen service ingress ,helm的作用就是通过打包的方式,把deployment,service,ingress 这些打包在一块,一键式的部署服务,类似yum 官方提供的一个类似于安装仓库…

大数据开发之Scala

第 1 章:scala入门 1.1 概述 scala将面向对象和函数式编程结合成一种简洁的高级语言 特点 1、scala和java一样属于jvm语言,使用时都需要先编译为class字节码文件,并且scala能够直接调用java的类库 2、scala支持两种编程范式面向对象和函数式…

Maven工程继承和聚合关系

1. Maven工程继承关系 1.1 继承概念 Maven 继承是指在 Maven 的项目中,让一个项目从另一个项目中继承配置信息的机制。继承可以让我们在多个项目中共享同一配置信息,简化项目的管理和维护工作。 1.2 继承作用 在父工程中统一管理项目中的依赖信息。 …

初识 JVM

什么是JVM JVM 全称是 J ava V irtual M achine,中文译名 Java虚拟机 。 JVM 本质上是一个运行在计算机上的程序,他的职责是运行 Java字节码文件 。 JVM的功能 Java语言如果不做任何优化,性能不如C、C等语言。 Java需要实时解释&…

什么是网络安全?网络安全概况

网络安全涉及保护我们的计算机网络、设备和数据免受未经授权的访问或破坏。 这个领域包括多种技术、过程和控制措施,旨在保护网络、设备和数据免受攻击、损害或未授权访问。网络安全涉及多个方面,包括但不限于信息安全、应用程序安全、操作系统安全等 …

仓储管理系统——软件工程报告(详细设计)④

详细设计 一、系统功能模块的划分 根据系统的功能性需求,本文将部队仓库管理系统分为以下六大模块:系统管理模 块、基础数据模块、出入库管理模块、库存管理模块、仓库信息管理模块、作业管理模 块,每个模块内部又分为很多小功能模块&#…

ADC的工作原理总结

ADC和DAC是联系连续和离散的重要桥梁,是信号采集和处理的重要环节。 这里我们先认识下ADC,聊一聊ADC的工作原理。 信号为何要相互转换? 模拟信号和数字信号的特点 自然界中大多数都是连续的模拟信号,模拟信号容易受到干扰&#…

华为AC+FIT AP组网配置

AC配置 vlan batch 100 to 101dhcp enableip pool apgateway-list 192.168.100.254 network 192.168.100.0 mask 255.255.255.0 interface Vlanif100ip address 192.168.100.254 255.255.255.0dhcp select globalinterface GigabitEthernet0/0/1port link-type trunkport trun…