当前位置: 首页 > news >正文

Java内存异常和垃圾回收机制

内存溢出异常 Java会存在内存泄漏吗?请简单描述

内存泄漏是指不再被使用的对象或者变量一直被占据在内存中。理论上来说, Java是有GC垃圾回收机制

的,也就是说,不再被使用的对象,会被GC自动回收 掉,自动从内存中清除。

但是, 即使这样,Java也还是存在着内存泄漏的情况,java导致内存泄露的原因 很明确:长生命周期的

对象持有短生命周期对象的引用就很可能发生内存泄露, 尽管短生命周期对象已经不再需要,但是因为

长生命周期对象持有它的引用而导 致不能被回收,这就是java中内存泄露的发生场景。

内存溢出异常

Java会存在内存泄漏吗?请简单描述

内存泄漏是指不再被使用的对象或者变量一直被占据在内存中。理论上来说, Java是有GC垃圾回收机制

的,也就是说,不再被使用的对象,会被GC自动回收 掉,自动从内存中清除。

但是,即使这样,Java也还是存在着内存泄漏的情况,java导致内存泄露的原因 很明确:长生命周期的

对象持有短生命周期对象的引用就很可能发生内存泄露, 尽管短生命周期对象已经不再需要,但是因为

长生命周期对象持有它的引用而导 致不能被回收,这就是java中内存泄露的发生场景。

垃圾收集器

简述Java垃圾回收机制

java中,程序员是不需要显示的去释放一个对象的内存的,而是由虚拟机自行 执行。在JVM中,有一

个垃圾回收线程,它是低优先级的,在正常情况下是不会 执行的,只有在虚拟机空闲或者当前堆内存不

足时,才会触发执行,扫面那些没 有被任何引用的对象,并将它们添加到要回收的集合中,进行回收。

GC是什么?为什么要GC

GC 是垃圾收集的意思(Gabage Collection,内存处理是编程人员容易出现问 题的地方,忘记或者错误

的内存

回收会导致程序或系统的不稳定甚至崩溃,Java 提供的 GC 功能可以自动监测 对象是否超过作用域从而

达到自动

回收内存的目的,Java 语言没有提供释放已分配内存的显示操作方法。

垃圾回收的优点和原理。并考虑2种回收机制java语言最显著的特点就是引入了垃圾回收机制,它使java程序员在编写程序时 不再考虑内存管理的问

题。

由于有这个垃圾回收机制,java中的对象不再有作用域的概念,只有引用的 对象才有作用域

垃圾回收机制有效的防止了内存泄露,可以有效的使用可使用的内存。

垃圾回收器通常作为一个单独的低级别的线程运行,在不可预知的情况下对内存 堆中已经死亡的或很长

时间没有用过的对象进行清除和回收。

程序员不能实时的对某个对象或所有对象调用垃圾回收器进行垃圾回收。 垃圾回收有分代复制垃圾回

收、标记垃圾回收、增量垃圾回收。

垃圾回收器的基本原理是什么?垃圾回收器可以马上回收 内存吗?有什么办法主动通知虚拟机进行垃圾

回收? 对于GC来说,当程序员创建对象时,GC就开始监控这个对象的地址、大小以及 使用情况。

通常,GC采用有向图的方式记录和管理堆(heap)中的所有对象。通过这种方式 确定哪些对象是"可达

",哪些对象是"不可达的"。当GC确定一些对象为"不可 达"时,GC就有责任回收这些内存空间。

可以。程序员可以手动执行System.gc(),通知GC运行,但是Java语言规范并不 保证GC一定会执行。

Java 中都有哪些引用类型?

强引用:发生 gc 的时候不会被回收。

软引用:有用但不是必须的对象,在发生内存溢出之前会被回收。

弱引用:有用但不是必须的对象,在下一次GC时会被回收。

虚引用(幽灵引用/幻影引用):无法通过虚引用获得对象,用

PhantomReference 实现虚引用,虚引用的用途是在 gc 时返回一个通知。

怎么判断对象是否可以被回收?

垃圾收集器在做垃圾回收的时候,首先需要判定的就是哪些内存是需要被回收 的,哪些对象是「存活」

的,是不可以被回收的;哪些对象已经「死掉」了,需 要被回收。

一般有两种方法来判断:

引用计数器法:为每个对象创建一个引用计数,有对象引用时计数器 +1,引用 被释放时计数 -1

当计数器为 0 时就可以被回收。它有一个缺点不能解决循环引用 的问题;

可达性分析算法:从 GC Roots 开始向下搜索,搜索所走过的路径称为引用链。 当一个对象到 GC

Roots 没有任何引用链相连时,则证明此对象是可以被回收的。

Java中,对象什么时候可以被垃圾回收

当对象对当前使用这个对象的应用程序变得不可触及的时候,这个对象就可以被 回收了。

垃圾回收不会发生在永久代,如果永久代满了或者是超过了临界值,会触发完全 垃圾回收(Full GC)。如

果你仔细查看垃圾收集器的输出信息,就会发现永久代 也是被回收的。这就是为什么正确的永久代大小

对避免Full GC是非常重要的原 因。

JVM中的永久代中会发生垃圾回收吗**

垃圾回收不会发生在永久代,如果永久代满了或者是超过了临界值,会触发完全 垃圾回收(Full GC)。如

果你仔细查看垃圾收集器的输出信息,就会发现永久代 也是被回收的。这就是为什么正确的永久代大小

对避免Full GC是非常重要的原 因。请参考下Java8:从永久代到元数据区

(译者注:Java8中已经移除了永久代,新加了一个叫做元数据区的native内存 区)

说一下 JVM 有哪些垃圾回收算法?

标记-清除算法:标记无用对象,然后进行清除回收。缺点:效率不高,无法清 除垃圾碎片。复制算法:按照容量划分二个大小相等的内存区域,当一块用完的时候将活着的 对象复制到另一块

上,然后再把已使用的内存空间一次清理掉。缺点:内存使用率不 高,只有原来的一半。

标记-整理算法:标记无用对象,让所有存活的对象都向一端移动,然后直接清 除掉端边界以外的

内存。

分代算法:根据对象存活周期的不同将内存划分为几块,一般是新生代和老年 代,新生代基本采用

复制算法,老年代采用标记整理算法。

标记-除算法**

标记无用对象,然后进行清除回收。

标记-清除算法(Mark-Sweep)是一种常见的基础垃圾收集算法,它将垃圾收 集分为两个阶段:

标记阶段:标记出可以回收的对象。

清除阶段:回收被标记的对象所占用的空间。

标记-清除算法之所以是基础的,是因为后面讲到的垃圾收集算法都是在此算法 的基础上进行改进的。

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

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

标记-清除算法的执行的过程如下图所示

复制算**

为了解决标记-清除算法的效率不高的问题,产生了复制算法。它把内存空间划 为两个相等的区域,每次

只使用其中一个区域。垃圾收集时,遍历当前使用的区 域,把存活对象复制到另外一个区域中,最后将

当前使用的区域的可回收的对象 进行回收。

:按顺序分配内存即可,实现简单、运行高效,不用考虑内存碎片。 :可用的内存大小缩小为

原来的一半,对象存活率高时会频繁进行复制。 复制算法的执行过程如下图所示标记-理算法**

在新生代中可以使用复制算法,但是在老年代就不能选择复制算法了,因为老年 代的对象存活率会较

高,这样会有较多的复制操作,导致效率变低。标记-清除 算法可以应用在老年代中,但是它效率不高,

在内存回收后容易产生大量内存碎 片。因此就出现了一种标记-整理算法(Mark-Compact)算法,与标

-整理 算法不同的是,在标记可回收的对象后将所有存活的对象压缩到内存的一端,使 他们紧凑的排

列在一起,然后对端边界以外的内存进行回收。回收后,已用和未 用的内存都各自一边。

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

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

标记-整理算法的执行过程如下图所示

分代收集算法

当前商业虚拟机都采用的垃圾收集算法。分代收集算法,顾名思义是根 据对象的存活周期将内

存划分为几块。一般包括年轻代老年代 和 永久代,如 图所示:说一下 JVM 有哪些垃圾回收器?

如果说垃圾收集算法是内存回收的方法论,那么垃圾收集器就是内存回收的具体 实现。下图展示了7

作用于不同分代的收集器,其中用于回收新生代的收集器 包括SerialPraNewParallel Scavenge,回

收老年代的收集器包括Serial OldParallel OldCMS,还有用于回收整个Java堆的G1收集器。不同收

集器 之间的连线表示它们可以搭配使用。

Serial收集器(复制算法): 新生代单线程收集器,标记和清理都是单线程,优点 是简单高效;

ParNew收集器 (复制算法): 新生代收并行集器,实际上是Serial收集器的多线程 版本,在多核CPU

环境下有着比Serial更好的表现;

Parallel Scavenge收集器 (复制算法): 新生代并行收集器,追求高吞吐量,高效 利用 CPU。吞吐量

= 用户线程时间/(用户线程时间+GC线程时间),高吞吐量可以高 效率的利用CPU时间,尽快完成程

序的运算任务,适合后台应用等对交互相应要求不 高的场景;

Serial Old收集器 (标记-整理算法): 老年代单线程收集器,Serial收集器的老年 代版本;

Parallel Old收集器 (标记-整理算法): 老年代并行收集器,吞吐量优先, Parallel Scavenge收集器

的老年代版本;

CMS(Concurrent Mark Sweep)收集器(标记-清除算法): 老年代并行收集 器,以获取最短回收

停顿时间为目标的收集器,具有高并发、低停顿的特点,追求最 短GC回收停顿时间。

G1(Garbage First)收集器 (标记-整理算法) Java堆并行收集器,G1收集器是 JDK1.7提供的一个新

收集器,G1收集器基于标记-整理算法实现,也就是说不会 产生内存碎片。此外,G1收集器不同

于之前的收集器的一个重要特点是:G1回收的范围是整个Java(包括新生代,老年代),而前六种

收集器回收的范围仅限于新生代 或老年代。详细介绍一下 CMS 垃圾回收器?

CMS 是英文 Concurrent Mark-Sweep 的简称,是以牺牲吞吐量为代价来获得 最短回收停顿时间的垃圾

回收器。对于要求服务器响应速度的应用上,这种垃圾 回收器非常适合。在启动 JVM 的参数加上“-

XX:+UseConcMarkSweepGC”来指定使用 CMS 垃圾回收器。 CMS 使用的是标记-清除的算法实现的,

所以在 gc的时候回产生大量的内存碎 片,当剩余内存不能满足程序运行要求时,系统将会出现

Concurrent Mode Failure,临时 CMS 会采用 Serial Old 回收器进行垃圾清除,此时的性能将会 被降

低。

新生代垃圾回收器和老年代垃圾回收器都有哪些?有什么 区别?

新生代回收器:SerialParNewParallel Scavenge

老年代回收器:Serial OldParallel OldCMS

整堆回收器:G1

新生代垃圾回收器一般采用的是复制算法,复制算法的优点是效率高,缺点是内 存利用率低;老年代回

收器一般采用的是标记-整理的算法进行垃圾回收。

简述分代垃圾回收器是怎么工作的?

分代回收器有两个分区:老生代和新生代,新生代默认的空间占比总空间的 1/3,老生代的默认占比是

2/3

新生代使用的是复制算法,新生代里有 3 个分区:EdenTo SurvivorFrom Survivor,它们的默认占

比是 8:1:1,它的执行流程如下:

 Eden + From Survivor 存活的对象放入 To Survivor 区;

清空 Eden  From Survivor 分区;

From Survivor  To Survivor 分区交换,From Survivor  To SurvivorTo Survivor  From

Survivor

每次在 From Survivor  To Survivor 移动时都存活的对象,年龄就 +1,当年 龄到达 15(默认配置是

15)时,升级为老生代。大对象也会直接进入老生代。

老生代当空间占用到达某个值之后就会触发全局垃圾收回,一般使用标记整理的 执行算法。以上这些循

环往复就构成了整个分代垃圾回收的整体执行流程。

存分配策略**

简述java内存分配与回收策率以及Minor GCMajor GC

所谓自动内存管理,最终要解决的也就是内存分配和内存回收两个问题。前面我 们介绍了内存回收,这

里我们再来聊聊内存分配。

对象的内存分配通常是在 Java 堆上分配(随着虚拟机优化技术的诞生,某些场 景下也会在栈上分配,

后面会详细介绍),对象主要分配在新生代的 Eden 区, 如果启动了本地线程缓冲,将按照线程优先在

TLAB 上分配。少数情况下也会直 接在老年代上分配。总的来说分配规则不是百分百固定的,其细节取

决于哪一种 垃圾收集器组合以及虚拟机相关参数有关,但是虚拟机对于内存的分配还是会遵 循以下几种

「普世」规则:

对象优先在 Eden 区分配

多数情况,对象都在新生代 Eden 区分配。当 Eden 区分配没有足够的空间进行 分配时,虚拟机将会发

起一次 Minor GC。如果本次 GC后还是没有足够的空 间,则将启用分配担保机制在老年代中分配内存。

这里我们提到 Minor GC,如果你仔细观察过 GC 日常,通常我们还能从日志中 发现 Major GC/Full

GC

Minor GC 是指发生在新生代的 GC,因为 Java 对象大多都是朝生夕死,所 有 Minor GC 非常频

繁,一般回收速度也非常快;Major GC/Full GC 是指发生在老年代的 GC,出现了 Major GC 通常会伴 随至少一次 Minor GC

Major GC 的速度通常会比 Minor GC  10 倍以上。

大对象直接进入老年代

所谓大对象是指需要大量连续内存空间的对象,频繁出现大对象是致命的,会导 致在内存还有不少空间

的情况下提前触发 GC 以获取足够的连续空间来安置新对 象。

前面我们介绍过新生代使用的是标记-清除算法来处理垃圾回收的,如果大对象 直接在新生代分配就会导

 Eden 区和两个 Survivor 区之间发生大量的内存复制。因此对于大对象都会直接在老年代进行分配。

长期存对象将进入老年代

虚拟机采用分代收集的思想来管理内存,那么内存回收时就必须判断哪些对象应 该放在新生代,哪些对

象应该放在老年代。因此虚拟机给每个对象定义了一个对 象年龄的计数器,如果对象在 Eden 区出生,

并且能够被 Survivor 容纳,将被 移动到 Survivor 空间中,这时设置对象年龄为 1。对象在 Survivor

中每「熬 过」一次 Minor GC 年龄就加 1,当年龄达到一定程度(默认 15) 就会被晋升 到老年代。

相关文章:

Java内存异常和垃圾回收机制

内存溢出异常 Java会存在内存泄漏吗?请简单描述 内存泄漏是指不再被使用的对象或者变量一直被占据在内存中。理论上来说, Java是有GC垃圾回收机制 的,也就是说,不再被使用的对象,会被GC自动回收 掉,自动…...

linux系统挂载逻辑卷和扩展逻辑卷组

fdisk /dev/vdb fdisk /dev/vdc在分区后需要修改分区类型为 8e,操作过程类似: [rootlocal ~] $ fdisk /dev/xvdb #### 选择磁盘 Command (m for help): m #### 帮助 Command actiona tog…...

WPF:WPF原生布局说明

前言 WPF在国内讨论度很小,我在这里记录一下WPF简单的原生控件是如何使用的,顺便回忆一下WPF的基础知识,有些忘记的比较厉害了 WPF简介 WPF是微软推出的桌面UI软件,是我觉得最早实现MVVM(数据驱动事务)&…...

SpringMVC常用注解用法

Spring MVC是基于Servlet API构建的原始Web框架。 MVC是Model View Controller的缩写即视图模型控制器,是一种思想,而Spring MVC是对该思想的具体实现。关于SpringMVC的学习我们需要掌握用户和程序的连接、获取参数以及返回数据三大部分。而这三大功能的…...

Liunx find locate 命令详解

文章目录 find补充说明语法选项参数实例根据文件或者正则表达式进行匹配否定参数根据文件类型进行搜索基于目录深度搜索根据文件时间戳进行搜索根据文件大小进行匹配删除匹配文件根据文件权限/所有权进行匹配借助-exec选项与其他命令结合使用搜索但跳过指定的目录find其他技巧收…...

JAVA并发专题(1)之操作系统底层工作的整体认识

一、分诺依曼计算机模型 现代计算机模型是基于-冯诺依曼计算机模型,计算机在运行时,先从内存中取出第一条指令,通过控制器的译码,按指令的要求,从存储器中取出数据进行指定的运算和逻辑操作等加工,然后再按…...

WiFi(Wireless Fidelity)基础(七)

目录 一、基本介绍(Introduction) 二、进化发展(Evolution) 三、PHY帧((PHY Frame ) 四、MAC帧(MAC Frame ) 五、协议(Protocol) 六、安全&#x…...

Agilent安捷伦33522B任意波形发生器

Agilent安捷伦33522B任意波形发生器30兆赫 2通道 为您最苛刻的测量生成全方位信号的无与伦比的能力 具有 5 倍低谐波失真的正弦波,可提供更纯净的信号 脉冲频率高达 30 MHz,抖动减少 10 倍,可实现更精确的计时 具有排序功能的逐点任意波形功能…...

PostgreSQL-如何创建并发索引

索引简介 索引是数据库中一种快速查询数据的方法。索引中记录了表中的一列或多列值与其物理位置之间的对应关系,就好比一本书前面的目录,通过目录中页码就能快速定位到我们需要查询的内容。 建立索引的好处是加快对表中记录的查找或排序,但…...

【大数据模型】使用Claude浅试一下

汝之观览,吾之幸也!本文主要聊聊Claude使用的流程,在最后对国内外做了一个简单问题的对比,希望国内的大数据模型更快的发展。 一、产品介绍 claude官网 Claude是一款由前OpenAI的研究员和工程师开发的新型聊天机器人,…...

鼎盛合——国产电量计芯片的分类与发展

电池技术在 200 余年的时间里不断演进,并在近 30 年的时间里取得了飞速发展,从最早期的铜-锌电池、铅酸电池,到目前的锂电池、钠电池,电池能量密度从早期的~10Wh/kg 飞速攀升至 200Wh/kg。回顾历史上来看,电池管理系统…...

交叉验证之KFold和StratifiedKFold的使用(附案例实战)

🤵‍♂️ 个人主页:艾派森的个人主页 ✍🏻作者简介:Python学习者 🐋 希望大家多多支持,我们一起进步!😄 如果文章对你有帮助的话, 欢迎评论 💬点赞&#x1f4…...

Cloud Kernel SIG月度动态:发布ANCK 5.10、4.19新版本,ABS新增仓库构建功能

Cloud Kernel SIG(Special Interest Group):支撑龙蜥内核版本的研发、发布和服务,提供生产可用的高性价比内核产品。 01 SIG 整体进展 发布 ANCK 5.10-014 版本。 发布 ANCK 4.19-027.2 版本。 ABS 平台新增 OOT 仓库临时构建功…...

JavaScript:new操作符

一、new操作符的作用 用于创建一个给定构造函数的实例对象 new操作符创建一个用户定义的对象类型的实例 或 具有构造函数的内置对象的实例。二、new一个构造函数的执行过程 2.1、创建一个空对象obj 2.2、将空对象的原型与构造函数的原型连接起来 2.3、将构造函数中的this绑定…...

XShell配置以及使用教程

目录 1、XShell介绍 2、安装XShell 1. 双击运行XShell安装文件,并点击“下一步” 2. 点击“我接受许可证协议中的条款”,点击“下一步” 3. 点击“浏览”更改默认安装路径,点击“下一步” 4. 直接点击“安装” 5. 安装完成&#xff0…...

Vue3 基础语法

文章目录 1.创建Vue项目1.1创建项目1.2 初始项目 2.vue3 语法2.1 复杂写法2.2 简易写法2.3 reactive(对象类型)2.4 ref(简单类型)2.5 computed(计算属性)2.6 watch(监听) 3.vue3 生命周期4.vue3 组件通信4.…...

【开源项目】Disruptor框架介绍及快速入门

Disruptor框架简介 Disruptor框架内部核心的数据结构是Ring Buffer,Ring Buffer是一个环形的数组,Disruptor框架以Ring Buffer为核心实现了异步事件处理的高性能架构;JDK的BlockingQueue相信大家都用过,其是一个阻塞队列&#xf…...

双向链表实现约瑟夫问题

title: 双向链表实现约瑟夫问题 date: 2023-05-16 11:42:26 tags: **问题:**知n个人围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去&…...

日心说为人类正确认识宇宙打下了基础(善用工具的重要性)

文章目录 引言I 伽利略1.1 借助天文望远镜获得了比别人更多的信息。1.2 确定了科学研究方法:实验和观测 II 开普勒三定律 引言 享有科学史上崇高地位的人,都需要在构建科学体系上有重大贡献。 日心说在哥白尼那里还是一个假说,伽利略拿事实…...

Kali-linux系统指纹识别

现在一些便携式计算机操作系统使用指纹识别来验证密码进行登录。指纹识别是识别系统的一个典型模式,包括指纹图像获取、处理、特征提取和对等模块。如果要做渗透测试,需要了解要渗透测试的操作系统的类型才可以。本节将介绍使用Nmap工具测试正在运行的主…...

Java版本电子招标采购系统源码:营造全面规范安全的电子招投标环境,促进招投标市场健康可持续发展

营造全面规范安全的电子招投标环境,促进招投标市场健康可持续发展 传统采购模式面临的挑战 一、立项管理 1、招标立项申请 功能点:招标类项目立项申请入口,用户可以保存为草稿,提交。 2、非招标立项申请 功能点:非招标…...

Java字符串知多少:String、StringBuffer、StringBuilder

一、String 1、简介 String 是 Java 中使用得最频繁的一个类了,不管是作为开发者的业务使用,还是一些系统级别的字符使用, String 都发挥着重要的作用。String 是不可变的、final的,不能被继承,且 Java 在运行时也保…...

中国20强(上市)游戏公司2022年财报分析:营收结构优化,市场竞争进入白热化

易观:受全球经济增速下行的消极影响,2022年国内外游戏市场规模普遍下滑。但中国游戏公司凭借处于全球领先水平的研发、发行和运营的能力与经验,继续加大海外市场布局,推动高质量发展迈上新台阶。 风险提示:本文内容仅代…...

如何自学C++编程语言,聊聊C++的特点,别轻易踩坑

为什么现在有那么多C培训班呢?因为这些培训班可以为学生安排工作,而外包公司因为缺人,需要做很多项目,可能需要在全国各地分配不同的程序员去干不同的项目,因此需要大量的程序员入职。这样,外包公司就会找培…...

算法Day07 | 454.四数相加II,383. 赎金信,15. 三数之和, 18. 四数之和

Day07 454.四数相加II383. 赎金信15. 三数之和18. 四数之和 454.四数相加II 题目链接:454.四数相加II 寻找两个数组之和,是否与另外两个数组之和有特定的关系。 因为数值可能跨度太大,选择使用下标表示为对应的数值大小,会很浪费…...

ps抠图、抠头发去背景等

方法一:背景橡皮擦 一、很早之前我们使用的是魔术棒工具,但现在我们可以使用Photoshop 有内置的“背景橡皮擦” 步骤: 第1步:在Photoshop中打开需要修的图。 第2步:单击并按住工具栏…...

计算机组成原理基础练习题第一章

有些计算机将一部分软件永恒地存于只读存储器中,称之为() A.硬件    B.软件C.固件    D.辅助存储器输入、输出装置以及外界的辅助存储器称为() A.操作系统    B.存储器 C.主机      D.外围设备完整的计算机系…...

[PyTorch][chapter 34][池化层与采样]

前言: 这里主要讲解一下卷积神经网络中的池化层与采样 目录 DownSampleMax poolingavg poolingupsampleReLu 1: DownSample 下采样,间隔一定行或者列进行采样,达到降维效果 早期LeNet-5 就采样该采样方式。 LeNet-5 2 Max pooling 最大值采样…...

Java进阶-字符串的使用

1.API 1.1API概述 什么是API ​ API (Application Programming Interface) :应用程序编程接口 java中的API ​ 指的就是 JDK 中提供的各种功能的 Java类,这些类将底层的实现封装了起来,我们不需要关心这些类是如何实现的,只需要…...

接口自动化框架对比 | 质量工程

一、前言 自动化测试是把将手工驱动的测试行为转化为机器自动执行,通常操作是在某一框架下进行代码编写,实现用例自动发现与执行,托管在CI/CD平台上,通过条件触发或手工触发,进行回归测试&线上监控,代替…...