jvm垃圾回收

2023-11-16

为什么需要垃圾回收?

​ 首先这个问题的话,主要因为内存是计算机中比较宝贵的财富,如果堆积的对象过多,可想而知,内存会用尽,出现内存溢出的问题,这也就是为什么需要垃圾回收的原因。

对什么区域进行回收?

​ jvm中的内存结构中,虚拟机栈,本地方法栈,程序计数器随着线程的创建而创建,随着线程的销毁而销毁,因此这三个区域是不需要垃圾回收的,需要注意的是程序计数器是唯一一个不存在oom异常的,具体是因为程序计数器只需要存储线程上下文切换的行号等消耗较小的内存地址,内存分配是可见的。只存下一个字节码指令的地址,消耗内存小且固定,无论方法多深,他只存一条。

​ 因此垃圾回收区域不言而喻,那就是方法区了。

如何判断是否需要回收?

​ 判断对象是否需要回收,根据引用进行判断。主要有两种策略:引用计数法可达性分析两种策略。但是两种策略都是基于对象引用的。

引用计数法具体而言就是,每个对象都会存储着被引用的次数,如果被引用就引用次数就会+1,如果没有被引用,那就是需要被回收的对象了。但是这种方法存在这样的问题,A.instance=B;B.instance=A;循环引用,那这个怎么判断呢?因此这种方法不是很实用,因此引出可达性分析这个策略。

可达性分析也就是从根节点(常量池中的static,final,虚拟机栈中,所有被同步锁synchronized的对象等),如果当前对象被引用,那么连接一条线。如果存在没有被引用的对象,那么可达性分析,肯定是不可达的,因此该对对象就是被回收的。
上述提到的引用在jdk1.2后出现了细粒度的引用名词。强引用,软引用,弱引用,虚引用。四种引用的区别参考强引用、软引用、弱引用、虚引用的区别和作用,以及例子

如何进行回收?

​该阶段是完成了判断哪些对象是死的,哪些对象是活的之后,进行的阶段。该阶段目前有四种策略:标记清除标记复制标记整理分代收集策略。

标记清除:分为先标记再清除两个步骤。标记的话,根据可达性分析,判读出哪些对象是活的,哪些对象是死的,完成死活的标记;标记完毕之后,对死去的对象完成清除。此策略是Lisp之父提出来的,但是存在这样的问题:在清除后,出现了大量的内存碎片,在写入数据的时候会随机写入,随机写入造成的问题就是会出现大对象可能到小的区域里了,装的对象少了,那么垃圾回收的频率也会高了,垃圾回收频率高的话,系统的性能肯定会有影响。

标记复制: 分为先标记然后完成从from幸存区到to幸存区存活对象的复制。首先值得注意的是,该策略将内存一分为二。其次即使先进行死活对象的标记,标记后,将活的的对象复制到另一个区域,然后清除都是死的对象。这种方法操作起来肯定是很快的,但是问题是啥呢?那就是将内存区域一分为二了**。内存利用率是不高的

标记整理: 分为先标记再整理两个步骤。同样也先进行标记,将活的和死的进行标记。然后将死的统一清除掉,将活的对对象完成整理,也就是将其内存的地址整理为连续的地址。这种方法会涉及到移动对象,在移动的过程中会STW,如果移动的时间越长,那STW越久,弊端可想而知,影响业务。

​ 移动和不移动都会存在问题,移动了,STW时间更久,不移动,内存碎片!看看分代收集方法能否解决移动和不移动存在的问题。

分代收集: 将堆中区域分为新生代和老年代,由于大量对象的创建都是在新生代中的伊甸园区,根据这个现象,可以使用标记复制策略,也就是先进行标记,然后将存活的对象完成从幸存区from到to区转移,这样能够加快处理效率。而老年代呢?老年代存在的对象大多数都是不容易被回收的对象,也就是活着的对象,使用标记清除或者标记整理方法都是可以的,也就是说将死活的对象标记出,将少量的死对象清除。

这里存在个问题?如何进入老年代。

进入老年代的条件很简单。1)如果是大对象,直接进入老年代。为啥?因为新生代和老年代的比例为1:2。新生代如果存储的都是大对象,来个大对象,完成一次轻量级gc,随着大对象频繁的插入,轻量gc频率增大,系统就会完犊子。2)如果对象头的分代年龄达到15,那么就进入老年代。为啥是15,可以说工业级和学术界的在测试环境下,测试到15代是一个合理的数值。分代年龄如何计算的呢?一次轻量gc,分代年龄就+1。

参考资料
[1]强引用、软引用、弱引用、虚引用的区别和作用,以及例子

[2] 深入理解java虚拟机 JVM高级特性与最佳实践

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

jvm垃圾回收 的相关文章

  • Spring Security 通过并发登录尝试将用户锁定

    我是安全新手 遇到了一个问题 该问题导致用户帐户被锁定 只有重新启动应用程序才能修复它 我有一个带有 spring security 4 0 2 RELEASE 应用程序的 spring boot 1 3 0 BUILD SNAPSHOT
  • 多线程环境下如何更好的使用ExecutorService?

    我需要创建一个库 其中包含同步和异步方法 executeSynchronous 等待直到有结果 返回结果 executeAsynchronous 立即返回一个 Future 如果需要 可以在其他事情完成后进行处理 我的图书馆的核心逻辑 客户
  • JavaFX Platform.runLater 的使用以及从不同线程访问 UI

    我有几个问题Platform runLater 我有一个 JavaFX 应用程序类 在这个类中 我运行一个线程 该线程从网络套接字读取数据 现在当我创建一个新的Stage在线程内部 系统抛出异常 JavaFX 事件调度程序线程和我的网络读取
  • 如何在Java 8中实现Elvis运算符?

    我有一个经典的 Elvis 运算符 案例 其中我调用每个可能返回 null 的方法并将它们链接在一起 thing nullableMethod1 a nullableMethod2 b nullableMethod3 在 Java 8 中
  • 实现与扩展:何时使用?有什么不同?

    请用易于理解的语言进行解释或提供某些文章的链接 extends is for 延伸一类 implements is for 实施一个接口 接口和常规类之间的区别在于 在接口中您不能实现任何声明的方法 只有 实现 接口的类才能实现方法 C 中
  • 在 IntelliJ 上进行 Google App Engine Java 开发?

    令人烦恼的是 Google App Engine 已成为其中的另一个项目 他们只发布 Eclipse 插件 如 Spring Webflow 而我更喜欢 IntelliJ 你能用IntelliJ成功运行本地测试环境吗 并调试 部署本地或实时
  • 使用 Android WebViewClient 启用特定 SSL 协议

    我的应用程序使用WebViewClient与服务器建立 SSL 连接 服务器配置为仅接受 TLSv1 1 及以上协议 使用 Android 时 如何检查哪些 SSL 协议是 a 支持的和 b 默认启用的WebViewClient在设备上 如
  • 静态方法的 Java 内存模型

    我来自操作系统和 C 语言背景 在代码编译时 世界很简单 需要处理和理解堆栈 堆文本部分等 当我开始学习 Java 时 我确实了解 JVM 和垃圾收集器 我对静态方法感到很有趣 根据我的理解 类的所有实例都会在堆中创建 然后被清理 但是 对
  • 如果基于 Spring 注解的控制器位于 jar 文件内,则该控制器无法工作

    我的子模块中有一些基于注释的控制器 这些模块作为 jar 文件部署 jar 文件中基于注释的控制器未加载到 spring 配置中 我使用 Eclipse 中的导出实用程序手动导出 jar 文件 有人遇到过这个问题吗 当您使用 Eclipse
  • 哈希码是否用于加速集合中的对象查找?

    IIUC 相同类型的两个不同对象可以存储在 HashSet 中 即使两个对象在以下情况下返回相同的值 hashCode 叫做 例如根据本文 https eclipsesource com blogs 2012 09 04 the 3 thi
  • 如何修复 Android 7.0 的 Spinner 模式下的 DatePickerDialog?

    我目前正在开发一个简单的项目 其中包含一个包含在 Web 视图中的网站 具有少量交互 以提高网站本身和 Android 移动设备之间的交互性 由于该网站包含用户生日的日期输入字段 因此我希望实现一个与所有设备兼容的旋转格式的日期选择器 我尝
  • 用 java 编写解释器时的 switch 或 if 语句

    当前的作业需要我编写一个程序 以一种非常微小且基本的编程语言 行为有点像 FORTRAN 来读取包含指令的文件并执行这些指令 基本上它是我猜的语言的简单解释器 它是完全线性的 所有语句都是按顺序定义的 并且只有字符串和整数变量 我需要查找和
  • 尝试在java中的Arraylist中查找对象的所有出现

    我有一个 Java ArrayList 我需要查找其中出现的所有特定对象 ArrayList indexOf Object 方法只找到一次出现 所以看来我还需要其他东西 我认为你不需要太花哨 以下应该可以正常工作 static
  • 是否可以为 azure blob 存储中的给定目录生成具有写入权限的 SAS(共享访问签名)

    我们的 blob 存储帐户结构 容器名称 simple 在这个容器内我们有 blob aa one zip aa two zip bb ss zip bb dd zip 是否可以生成对aa 目录 有写权限 但对bb 目录 没有访问权限的SA
  • 在Java中多次读取System.in会导致IOException?

    我正在尝试创建一个小命令行游戏来强化我在过去几个月中在 Java 中学到的一些东西 我正在尝试创建一个名为 readInput 的方法 它返回一个我可以一次又一次调用的字符串 第一次它工作正常 但第二次它会导致 IO Exception 如
  • 如何使用云打印打印Android活动显示

    我正在尝试将 Google 云打印实现到应用程序中 遵循集成指南 https developers google com cloud print docs android 我试图通过打印 google com 来保持基本 单击我创建的打印按
  • 找不到符号assertEquals

    我正在尝试为计算器编写第一个单元测试 但 NetBeans 说它找不到该符号assertEquals和注释 Test 我应该包括一些东西吗 我正在使用 NetBeans 7 3 1 和 W7 package calculator impor
  • 如果抛出RuntimeException,是否可以将其作为异常捕获?

    如果我有一个try抛出一个块RuntimException子类 可以是后续的catch块将其捕获为Exception 具体来说 public class MyAppException extends RuntimeException In
  • 如何从spark中的hbase表中获取所有数据

    我在 hbase 中有一个大表 名称为 UserAction 它具有三个列族 歌曲 专辑 歌手 我需要从 歌曲 列族中获取所有数据作为 JavaRDD 对象 我尝试了这段代码 但效率不高 有更好的解决方案来做到这一点吗 static Spa
  • 编写自定义 Eclipse 调试器

    EDIT 一定有某种方法可以解决这个问题 而无需编写全新的调试器 我目前正在研究在现有 java 调试器之上构建的方法 如果有人对如何获取 Java 调试器已有的信息 有关堆栈帧 变量 原始数据等 有任何想法 那将非常有帮助 我想要做的是我

随机推荐

  • 打印堆栈

    traceback print stack
  • SVN相关

    svn更新失败提示cleanup的解决方法 问题解决 https blog csdn net study4034 article details 80656882 注意关闭unity SVN更新后提示 One or more files a
  • 卷(二)C++___二刷

    Chapter 8 Type Conversion and Function Overloading 8 1 Implicit type conversion coercion The integer value 3 might be st
  • 合宙Air103

    基础资料 基于Air103开发板 Air103 LuatOS 文档 上手 开发上手 LuatOS 文档 探讨重点 对官方SPI FLASH demo中功能的复现 进行相关内容的学习及探讨 实现功能 功能 lua快速驱动 W25QXX XX代
  • windows:自定义内网ip后无法上网

    有可能能是ip冲突
  • Markdown给公式添加编号

    Markdown给公式添加编号 a 2 b 2 c 2 tag 1 2 由公式 1 2 即可得到结论
  • Eureka集群原理

    问题 微服务RPC远程服务调用最核心的是什么 高可用 试想你的注册中心只有一个only one 它出故障了那就呵呵o o了 会导致整个微服务环境不可用 解决办法 搭建Eureka注册中心集群 实现负载均衡 故障容错 Eureka集群的原理
  • c语言之字符串数组

    还是在写图的存储结构的时候 遇到了问题 就是如何在一个数组中存放字符串 我相信这个问题 对于面向对象的编程语言来说 轻而易举 比如对于Java来说 直接像下面就可以了 但是c语言没有String这个类型 能想到存放字符串的数据类型就是cha
  • 千万级SQL Server数据库表分区的实现

    一般在千万级的数据压力下 分区是一种比较好的提升性能方法 本文将介绍SQL Server数据库表分区的实现 AD 最近使用SQL SERVER一个的缓存 数据量一天100w的速度增长 同时接受客户查询 速度由于数据量越来越大越来越慢 这里感
  • vue3+ts 时间戳转日期格式

    时间戳转换成日期格式 调用 timestampToTime 1680498539 日期补0 const getzf num number string number gt const numShow string number num lt
  • EXCEL 做的购订单管理系统

    EXCEL 做的购订单管理系统 需要的下载 采购订单管理系统 01 总体说明 1 本系统主要用于采购订单以及付款管理 可进行供应商信息 产品信息的基础信息维护 可录入采购明细对采购金额进行付款 可对采购按照产品和采购日期范围查询 对采购明细
  • memset和memset_s

    void memset void s int ch size t n 函数解释 将s中前n个字节 typedef unsigned int size t 用 ch 替换并返回 s memset 作用是在一段内存块中填充某个给定的值 它是对较
  • TTransportException: java.net.ConnectException: Connection refused: connect异常

    看视频学用Thrift时遇到的 环境 win7 thrift 0 12 0 python37 jdk1 8 IDE IJ PC 本机java客户端 连 本机python服务器 部分代码 serverSocket TSocket TServe
  • 数据挖掘-数据探索(EDA)

    数据探索 EDA Exploratory Data Analysis 1 EDA的作用 EDA的作用主要在于熟悉并了解数据集 对数据集进行处理 以便接下来机器学习或者深度学习使用 了解数据集之后 接下来就是了解数据集中各变量间的相互关系 变
  • 2020年6月100篇最新GAN论文汇总

    点击上方 机器学习与生成对抗网络 关注 星标 获取有趣 好玩的前沿干货 戳我 查看GAN的系列专辑 据不完全统计 GAN在CVPR2020上超115篇之多 其中 可看到GAN在朝着无监督 自监督 弱监督 半监督 少样本 单样本 零样本 多模
  • 2024王道408数据结构P144 T16

    2024王道408数据结构P144 T16 思考过程 首先看题目 要求我们把二叉树的叶子结点求出来并且用链表的方式存储 链接时用叶结点的右指针来存放单链表指针 我们很清楚可以看出来能用中序遍历 递归的方式实现 因为第一个叶子结点在整棵树的最
  • Android中拍照和录像功能

    目前Android中有很多项目需要实现拍照及录像功能 通常都使用camera和sufaceView实现 整个过程较为繁琐 并且代码量比较大 偶然在github上发现一个很好用的框架 在这里做一个简单介绍 后附github地址 gif 原项目
  • SpringBoot——整合Mongodb

    简单介绍 Mongdb是一个开源 高性能 无模式的文档型数据库 NoSQL数据库产品中的一种 是最像关系型数据库的非关系型数据库 使用场景 用户数据 存储位置 数据库 特征 永久性存储 修改频率极低 游戏装备数据 存储位置 数据库 Mong
  • 2023华为od机试 Java实现【关联子串】

    题目 我们有两个字符串 分别叫做 str1 和 str2 现在规定 如果 str1 的排列组合只要有一个是 str2 的子串 我们就称str1是str2的关联子串 请返回子串在str2的起始位置 若不是关联子串则返回 1 示例1 输入输出示
  • jvm垃圾回收

    为什么需要垃圾回收 首先这个问题的话 主要因为内存是计算机中比较宝贵的财富 如果堆积的对象过多 可想而知 内存会用尽 出现内存溢出的问题 这也就是为什么需要垃圾回收的原因 对什么区域进行回收 jvm中的内存结构中 虚拟机栈 本地方法栈 程序