JVM系列之对象是否存活

2023-10-29

前言

之前我们讲过了JVM的内存区域和内存溢出,今天我们谈下处于JVM中的对象的问题,这些对象是否存活,如何判断,又如何去处理呢,带着这些疑问我们开启今天的JVM之旅。

 

如何判断对象是否存活?

  • 引用计数算法:给对象中添加一个引用计数器,每当有一个地方引用它时,计数器的值就+1,当引用失效时,计数器的值就-1;当计数器的值为0时,就表示该对象为不可用对象;

    优点:引用计数算法实现简单,效率也很高

    缺点:很难解决对象之间相互循环引用时的对象存活判断,例如对象A和B相互引用对方,即使A和B永远都不会再被访问,但是因为AB彼此持有对方的引用导致,AB的计数器永远不会为0,也就不会死亡,引用计数器无法通知GC收集器回收它们,正是因为这一点,主流的JVM都没有选用引用计数法来管理内存。

  • 可达性分析算法:通过一系列的GC Root对象作为起点,从这些起点出发向下搜索,搜索所走过的痕迹称为引用链,当一个对象到起点GC Root没有任何引用链相连接时,就说明该对象是不可用的

    如图1234到GC Root都是可达的因此都是可用的,567都是不可用的。

  • 扩展什么是引用:如果引用类型的数据中存储的数值代表的是另一块内存的起始地址,就称这块内存为一个引用,在这种定义下,一个对象只有被引用和未被引用两种状态,当我们遇到下面这种对象就显得有心无力了:当内存空间足够时,对象保留,内存紧张时,则被抛弃;

    对于这种对象,Java在1.2版本之后对引用进行了加强,提出了强引用、软引用、弱引用和虚引用4种引用类型,引用强度依次递减,下面我们将依次介绍:

    强引用:在代码中普通存在的对象,例如直接new出来的对象,这类对象只要强引用还存在,垃圾收集器永远不会回收被引用的对象;

    软引用:描述一些还有用但是并非必需的对象,这类对象在将要发生内存溢出之前,会被列进回收范围之中进行第二次回收,如果在此次回收中还是没有足够的内存,就会抛出内存溢出异常(SoftReference);

    弱引用:描述一些非必需的对象,这类对象只能存活到下一次垃圾回收之前,当垃圾收集器回收时,无论当前内存是否足够,被弱引用关联的对象都会被回收掉(WeakReference);

    虚引用:最弱的一个引用类型,被虚引用关联的对象完全不会影响其生存时间,可以理解为没有引用一样,但是又有点区别,区别在于,弱引用关联的对象在被收集器回收的时候能收到一个系统回收通知(PhantomReference);

 

对象死亡的过程?

注释:finalize()方法可以使用try-finally替换

 

方法区如何回收?

方法区(HotSpot永久代)回收其实是一个不常被关注的地方,主要原因在于两点,第一:虚拟机规范中不要求对方法区进行回收;第二点:方法区回收的性价比比较低,回收效率比较低。但是我们还是做个了解比较好,接下来我们就讲下方法区的回收。

主要分为两个方面:废弃常量和无用的类

废弃常量:如果常量池中的某个常量不被任何对象引用,也没有任何地方引用这个字面量,则会在垃圾回收的时候,被清理出常量池(常量池中其他类、方法、字段也类似);

无用的类:无用的类需要满足下面3点才会被回收

  • 该类所有的实例都已经被回收,即堆中不存在该类的任何实例

  • 加载该类的ClassLoader已经被回收

  • 该类对应的class对象没有在任何地方被引用,无法在任何地方通过反射访问该类的方法

当无用的类满足上述3点即满足回收条件,但是具体是否被回收还可以由-Xnoclassgc参数来控制

 

以上就是今天的所有内容,下节我们将隆重介绍几大垃圾收集算法。

 

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

JVM系列之对象是否存活 的相关文章

  • G1 GC 单个、非常长的年轻 GC 发生且 ParallelGCThreads=1

    I set ParallelGCThreads 1并使用G1 GC 所有其他JVM设置为默认设置 我跑PageRank在 Spark 1 5 1 上 有两个 EC2 节点 每个节点有 100 GB 堆 我的堆使用情况图如下 红色区域 年轻代
  • Cassandra DB 中的日期插入:重要的 1 小时轮班问题(后续)

    这是这个的后续其他原帖 https stackoverflow com questions 23080188 date insertion in cassandra db non trivial 1h shift issue 2308355
  • 显示JVM中当前运行的所有线程组和线程

    所以我的任务是显示所有线程组以及当前在 JVM 中运行的属于这些组的所有线程 输出时应首先显示线程组 然后在下面显示该组中的所有线程 这是针对所有线程组完成的 目前 我的代码将仅显示每个线程组 然后显示每个线程 但我不确定如何达到我所描述的
  • Lambda 性能改进,Java 8 与 11

    我对 lambda 与方法参考运行了一些 JMH 测试 看起来类似于 IntStream reduce Integer max vs IntSream reduce i1 i2 gt Integer max i1 i2 我注意到 在 Jav
  • 估计 64 位 Java 中最大安全 JVM 堆大小

    在分析存在一些问题的 64 位 Java 应用程序的过程中 我注意到分析器本身 YourKit 正在使用真正大量的内存 我在 YourKit 启动脚本中得到的是 JAVA HEAP LIMIT Xmx3072m XX PermSize 25
  • JVM HotSpot 上的 Java 异常计数器

    我想知道是否可以在不更改应用程序代码的情况下记录 JVM 级别上发生的每个异常 我所说的每个异常是指捕获和未捕获的异常 我想稍后分析这些日志并按异常类型 类 对它们进行分组 并简单地按类型对异常进行计数 我正在使用热点 也许有更明智的理由这
  • 如何减少Scala中创建的对象数量?

    我正在 Scala 中编写一个计算机图形应用程序 它使用 RGB 类返回图像中某个点的颜色 正如你可以想象的 返回颜色 RGB 对象的函数被调用了很多次 class RGB val red Int val green Int val blu
  • 什么触发了java垃圾收集器

    我对 Java 中垃圾收集的工作原理有点困惑 我知道当不再有对某个对象的实时引用时 该对象就有资格进行垃圾回收 但是如果它有对实时对象的引用怎么办 可以说我有一个节点集合 它们再次引用更多节点 List 1 gt Node a gt Nod
  • 在intellij中为java启用ssl调试

    从我的问题开始 上一期尝试通过 tls ssl 发送 java 邮件 https stackoverflow com questions 39259578 javamail gmail issue ready to start tls th
  • Java 接口合成方法生成,同时缩小返回类型

    我有 2 个接口和 2 个返回类型 interface interfaceA Publisher
  • 一个好的 Java VM 中方法调用的开销是多少?

    有人可以提供反汇编的机器代码汇编程序列表吗 我的意思是 与 C 中的普通函数调用相比 肯定有一些开销 VM 需要跟踪调用以查找热点 并且当它使用编译代码时 如果新加载的类需要重新编译 它需要提供动态更改编译方法的方法 我想某处也有返回堆栈溢
  • Intellij Idea 使用什么 JVM 来启动?

    我是 Eclipse 用户 最近决定尝试 Intellij Idea 我的操作系统是 Ubuntu 12 使用 Eclipse 时 可以通过在 eclipse ini 中指定来轻松选择用于启动 Eclipse 的 JVM http wiki
  • Scala 中的多个类型下限

    我注意到tuple productIterator总是返回一个Iterator Any 想知道是否无法设置多个下限 因此它可能是最低公共超类型的迭代器 我尝试并搜索了一下 但只发现this https stackoverflow com q
  • 为什么不在下一个 JVM 中删除类型擦除呢?

    Java 在 Java 5 中引入了泛型类型擦除 因此它们可以在旧版本的 Java 上运行 这是兼容性的权衡 我们已经失去了这种兼容性 1 https stackoverflow com questions 22610400 a progr
  • 如何在Java中计算对象的数字年龄[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我想知道Java中对象的年龄 当我们使用new关键字时 Java中用户定义的对象被创建 但是什么时候它会被销毁 是跨越JVM的perm
  • Java 类:匿名类、嵌套类、私有类

    有人能解释一下Java中匿名类 嵌套类和私有类之间的区别吗 我想知道与每个相关的运行时成本以及每个编译器的方法 这样我就可以掌握哪个最适合用于例如性能 编译器优化的潜力 内存使用以及其他 Java 编码人员的普遍可接受性 我所说的匿名类是指
  • OQL 包中的所有实例

    是否有可能在OQL检索属于一个包的所有对象 或者我可以查询wildcards 正如 haridsv 建议我尝试过的 SELECT from com example and SELECT a from com example but in V
  • 通过SOCKS代理连接Kafka

    我有一个在 AWS 上运行的 Kafka 集群 我想用标准连接到集群卡夫卡控制台消费者从我的应用程序服务器 应用程序服务器可以通过 SOCKS 代理访问互联网 无需身份验证 如何告诉 Kafka 客户端通过代理进行连接 我尝试了很多事情 包
  • 容器中的 JVM 计算处理器错误?

    最近我又做了一些研究 偶然发现了这一点 在向 OpenJDK 团队抱怨之前 我想看看是否有其他人观察到这一点 或者不同意我的结论 因此 众所周知 JVM 长期以来忽略了应用于 cgroup 的内存限制 众所周知 现在从 Java 8 更新某
  • 使用 Coldfusion 11 的 CFdirectory,文件名中存在非 ASCII 字符问题

    我有一个类似的问题 ColdFusion CFDirectory 和法语 https stackoverflow com questions 1715632 coldfusion cfdirectory and the french从而没有

随机推荐