Java垃圾收集原理

news2025/1/18 16:53:47

程序计数器、虚拟机栈、本地方法栈这三个区域随线程而灭,栈中栈帧的内存大小也是在确定的。这几个区域的内存分配和回收都具有确定性,因此不需要过多考虑如何回收。

Java堆和方法区这两个区域有着很显著的不确定性

  • 一个接口的实现类需要的内存可能不一样
  • 一个方法所执行的不同条件分支所需要的内存可能不一样

只有处于运行期间,才能知道程序需要多少内存,这部分内存的分配和回收是动态的。垃圾收集器关注的正是这部分内存。

判断对象是否有用

  1. 引用计数算法

每个对象中添加一个引用计数器,每当有一个地方引用它,计数器值就加一;当失去一个引用时,计数器值就减一。任何时刻计数器为0的对象就是不可能再被使用的。

但是这个算法不能解决循环引用的问题。

public class ReferenceCountingGC {
    public Object instance = null;
    private static final int _1MB = 1024*1024;
    private byte[] bigSize = new byte[2*_1MB];

    public static void testGC() {
        ReferenceCountingGC objA = new ReferenceCountingGC();
        ReferenceCountingGC objB = new ReferenceCountingGC();
        objA.instance = objB;
        objB.instance = objA;
        objA = null;
        objB = null;
        System.gc();
    }
}

但是实际上这两个对象可以被回收,所以实际上HotSpot使用的并不是这种内存回收方式。

  1. 可达性算法分析

通过这个算法用来判断对象是否存活。这个算法的基本思路就是通过一系列称为“GC Roots”的根对象作为起始节点集,从这些节点开始,根据引用关系向下搜索,搜索过程所走过的路径称为“引用链”,如果某个对象不在链上,则说明这个对象可被回收。

可作为GC Roots的对象包括以下几种:

  • 虚拟机栈中引用的对象
  • 方法区中类静态属性引用的对象
  • 方法区常量引用的对象,譬如字符串常量池里的引用
  • 本地方法栈中Native方法引用的对象
  • Java虚拟机内部的引用
  • 所有被同步锁持有的对象
  • 反映Java虚拟机内部情况的JMXBean

除了这些还有其他对象可以临时性地加入GC Roots集合。

引用扩展

JDK 1.2之前,如果reference类型的数据中存储的数值代表的是另一块内存的起始地址,就称这个reference数据是引用。

JDK 1.2之后,引用扩展为了强引用、软引用、弱引用、和虚引用4种,这4中引用强度依次减弱。

  • 强引用指的是类似Object obj = new Object()的引用关系。只要强引用关系还存在,垃圾收集器就永远不会回收掉被引用的对象。
  • 软引用用来描述一些还有用,但非必须的对象。只被软引用关联着的对象,在系统要发生内存溢出异常前,会把这些对象列进回收范围之中进行第二次回收,如果这次回收还没有足够的内存,才会抛出内存溢出异常。通过SoftReference类来实现软引用。
  • 弱引用也是用来描述非必须对象的,但是只被弱引用关联着的对象,无论系统内存是否充足,在进行垃圾回收时都会被回收掉。通过WeakReference类来实现弱引用。
  • 一个对象是否有虚引用的存在,完全不会对其生存时间构成影响,也无法通过虚引用来取得一个对象实例。为一个对象设置虚引用关联的唯一目的只是为了能在这个对象被回收时收到一个系统通知。通过PhantomReference类来实现虚引用。

回收过程

即使是在可达性分析算法中被判定为不可打的对象,也不一定会被回收。一个对象真正被回收需要经过两次标记过程:当这个对象不可达时进行第一次标记,随后判断这个对象是否有必要执行finalize()方法;如果这个对象没有覆盖finalize()方法或者finalize()方法已经被虚拟机执行过了,那么就被视为“没有必要执行”。

如果这个对象被判定确有必要执行finalize()方法,那这个对象会被放置在一个F-Queue的队列中,并稍后由一条由虚拟机自动建立的、低调度优先级的Finalizer线程去执行它们的finalize()方法。如果这个对象在finalize()方法中把自己和引用链上的任何一个对象关联了起来,那么这个对象就逃过了第二次标记。没有逃过标记的对象会被回收。

public class FinalizeEscapeGC {
    public static FinalizeEscapeGC SAVE_HOOK = null;
    public void isAlive() {
        System.out.println("yes, i am still alive :)");
    }

    @Override
    protected void finalize() throws Throwable {
        super.finalize();
        System.out.println("finalize method executed!");
        FinalizeEscapeGC.SAVE_HOOK = this;
    }

    public static void main(String[] args) throws Throwable {
        SAVE_HOOK = new FinalizeEscapeGC();
        SAVE_HOOK = null;
        System.gc();
        Thread.sleep(500);

        if(SAVE_HOOK != null) {
            SAVE_HOOK.isAlive();
        } else {
            System.out.println("no, i am dead :(");
        }

        SAVE_HOOK = null;
        System.gc();
        Thread.sleep(500);

        if(SAVE_HOOK != null) {
            SAVE_HOOK.isAlive();
        } else {
            System.out.println("no, i am dead :(");
        }
    }
}

运行结果

image-20230413204529484

回收方法区

方法区的垃圾收集主要回收两部分内容:废弃的常量和不再使用的类。

判断一个常量是否废弃相对简单(查看引用个数),而要判定一个类是否不再使用,需要同时满足下面三个条件

  • 该类的所有实例都已经被回收,Java堆中不存在该类及其派生子类的实例
  • 加载该类的类加载器已经被回收(只出现在自己设计类加载器的场景)
  • 该类对应的java.lang.Class对象没有在任何地方被引用,无法在任何地方通过反射访问该类的方法

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

软考第七章 下一代互联网

下一代互联网 1.IPv6 IPv4的缺陷: 网络地址短缺路由速度慢,IPv4头部多达13个字段,路由器处理的信息量很大缺乏安全功能不支持新的业务模式 关于PIv6的研究成果都包含在1998年12月发表的RFC 2460文档中 1.1 IPv6分组格式 版本&#xff1a…

量子退火Python实战(3):投资组合优化(Portfolio) MathorCup2023特供PyQUBO教程

文章目录前言一、什么是投资组合优化?二、投资组合优化建模1. 目标函数:回报2.约束函数:风险3.最终优化目标函数三、基于PyQUBO实现1. 获取数据2. 数据处理3. 目标函数PyQUBO实现4. OpenJij实施优化总结前言 提示:包含pyQUBO用法…

硬件语言Verilog HDL牛客刷题day11 A里部分 和 Z兴部分

1.VL72 全加器 1.题目: ① 请用题目提供的半加器实现全加器电路① 半加器的参考代码如下,可在答案中添加并例化此代码。 2. 解题思路 (可以看代码) 2.1 先看 半加器 s 是加位 , C 是进位。 2.2 再看全加器 …

2023年新手如何选择云服务器配置来部署自己的网站?

现在做网站的人越来越少了,没有以前那种百万网站站长的势头。但是,不论个人站长还是企业,只要网上开展业务其实都会需要自己网站或小程序、APP等平台。如今,很少有人使用虚拟主机,但是独立服务器成本高,一般…

【2023】Kubernetes-网络原理

目录kubernetes网络模型kubernetes网络实现容器到容器之间通信Pod之间的通信Pod到Service之间的通信集群内部与外部组件之间的通信开源容器网络方案FlannelCalicokubernetes网络模型 Kubernetes网络模型设计的一个基础原则是:每个Pod都拥有一个独立的IP地址&#x…

异地远程访问本地SQL Server数据库【无公网IP内网穿透】

文章目录1.前言2.本地安装和设置SQL Server2.1 SQL Server下载2.2 SQL Server本地连接测试2.3 Cpolar内网穿透的下载和安装2.3 Cpolar内网穿透的注册3.本地网页发布3.1 Cpolar云端设置3.2 Cpolar本地设置4.公网访问测试5.结语转发自CSDN远程穿透的文章:无需公网IP&a…

哪吒探针 - Windows 和Linux端agent安装(详细注意版)

一、Windows端agent安装配置 环境准备 环境: Windows 服务器软件:哪吒探针点击下载、nssm 点击下载(探针agent和nssm都要下载准备好) 设置环境变量下载软件后,解压到任意位置,然后按 winR 打开运行窗口,输入 sysdm.cpl 打开系统属性–>高级…

基于GIS/SCADA的智慧燃气数字孪生Web3D可视化系统

在低碳经济快速发展的今天,天然气在我国能源结构的占比逐年提高,安全供气成为关乎民生福祉、经济发展和社会和谐的大事。 自我国开展燃气铺设以来,经过长期运营的家用燃气和工业燃气设备管道设施设备基础差、检维修难度大,且传统燃…

[Java Web]会话跟踪技术

⭐作者介绍:大二本科网络工程专业在读,持续学习Java,努力输出优质文章 ⭐作者主页:逐梦苍穹 ⭐所属专栏:Java Web 目录1、会话跟踪技术概述2、数据共享3、Cookie4、Session5、Cookie和Session的区别6、总结1、会话跟踪…

大数据应用——Hadoop运行模式(伪分布式运行)

4.2 伪分布式运行模式4.2.1 启动HDFS并运行MapReduce程序1. 分析 (1)配置集群(2)启动、测试集群增、删、查没有改(多台机子麻烦)(3)执行WordCount案例2. 执行步骤(1&…

NestJS:TypeORM 连接mysql数据库,增删改查

一、安装数据库相关模块 pnpm add nestjs/typeorm typeorm mysql package.json 二、navicat创建nestjs_base数据库,创建products数据表,添加记录 创建nestjs数据库,创建products数据表 navicat:连接MySQL,创建库、表…

【GPT4】微软 GPT-4 测试报告(1)总体介绍

欢迎关注【youcans的AGI学习笔记】原创作品,火热更新中 微软 GPT-4 测试报告(1)总体介绍 微软 GPT-4 测试报告(2)多模态与跨学科能力 微软 GPT-4 测试报告(3)编程能力 微软 GPT-4 测试报告&…

腾讯云SSL证书格式类型及服务器支持说明

腾讯云SSL证书支持服务器类型有Tomcat、Apache、Nginx、IIS等,SSL证书格式包括crt、key、pfx、JKS、pem等格式,腾讯云百科整理了腾讯云SSL证书支持服务器类型格式对照表: 腾讯云SSL证书格式和服务器支持对照表 腾讯云SSL证书格式和服务器支持…

数据库系统工程师——第三章 数据结构与算法

文章目录📂 第三章、数据结构与算法 📁 3.1 线性结构 📖 3.1.1 线性表 📖 3.1.2 栈和队列 📖 3.1.3 串 📁 3.2 数组和矩阵 📁 3.3 树和图 📖 3.3.1 树 📖 3.3.2 图 &…

QCustomPlot实现极坐标图——QtWidgets

前言 前面用QtChart实现了极坐标图,感觉不是很方便,特别是一些点的图形,一般需要自己绘制,而QCustomPlot自带挺多的;还有极坐标的角度轴(即 圆圈),相比起来,QCustomPlot…

HTML+CSS+JS 学习笔记(一)———HTML(上)

🌱博客主页:大寄一场. 🌱系列专栏:前端 😘博客制作不易欢迎各位👍点赞⭐收藏➕关注 目录 代码开发工具 概念 HTML模板 body元素的常用属性 HTML 控制标记(标签)的类型 HTML语法…

数据库系统概论(第五版) 王珊 第四章 课后习题答案

目录 (一)数据库安全性の概念 1. 什么是数据库的安全性 2.数据库安全性和计算机系统的安全性有什么关系? 4.试述实现数据库安全性控制的常用方法和技术 5.什么是数据库中的自主存取控制方法和强制存取控制方法? (二)考试…

FMCW激光雷达,未来已来

2021年1月,一家名为Avea的激光雷达初创公司,与日本电装宣布达成合作协议,双方将共同推进FMCW(调频连续波)激光雷达的量产,目标是满足大众市场的需求。 众所周知,目前,大多数车载激光…

简单明了的说明STM32的PWM原理以及实现方法

申明以下都是个人理解,仅供参考。如果错误欢迎指教。本文不讲底层,根据实际使用来逆向讲解。 1.什么是pwm? pwm最简单的理解就是“功率”,调节PWM的占空比就是调节功率。 2.如何调节占空比? 图1 根据图1很容易看出…

3d坦克大战

文章目录一、 介绍二、 导入美术资源、调节光亮三、 坦克脚本四、 添加坦克移动效果、挂载脚本五、 制作子弹预制体、脚本六、 子弹发射点、发射子弹脚本七、 坦克血量脚本八、 设置相机视角九、 设置环形滑动条,表示hp十、 下载素材包一、 介绍 有两种模式&#x…