【Java 虚拟机原理】垃圾回收算法 ( Java 虚拟机内存分区 | 垃圾回收机制 | 引用计数器算法 | 引用计数循环引用弊端 )

简介: 【Java 虚拟机原理】垃圾回收算法 ( Java 虚拟机内存分区 | 垃圾回收机制 | 引用计数器算法 | 引用计数循环引用弊端 )

文章目录

一、Java 虚拟机内存分区

二、垃圾回收机制

三、引用计数器算法 ( 无法解决循环引用问题 )





一、Java 虚拟机内存分区


Java 虚拟机内存分区 :


所有线程共有的内存区域 : 堆 , 方法区 ( 元空间 ) ;


方法区 : 存放 静态变量 , 常量 , class 编译后的代码数据 , 永久代对象数据 ( 很少 GC , 永久代的 GC 就是卸载常量池及类型 ) ;

堆 : 存放 创建的 对象实例 , 所有线程共享这个区域 , 堆是 垃圾回收的重点管理区域 ; 有 年轻代 , 老年代 空间 ;

年轻代 : 占整个 堆内存的 1 3 \cfrac{1}{3}

3

1


 的空间 ;

Eden 区 : 占 年轻代的 80 % 80\%80% 空间 ;

Survivor 区 : 占年轻代的 20 % 20\%20% 空间 ;

From : 占 年轻代的 10 % 10\%10% 空间 ;

To : 占 年轻代的 10 % 10\%10% 空间 ;

老年代 : 占整个 堆内存的 2 3 \cfrac{2}{3}

3

2


 空间 ; 老年代又称为永生代 , 只要程序没有 OOM 崩溃 , 这些 对象都是永生的 ; 比较大的对象直接放入老年代 ;

线程私有的内存区域 : 线程栈 , 本地方法栈 , 程序计数器 ; 每个线程都会分配上述 3 个内存区域 ;


虚拟机栈 ( 线程栈 ) : 主要管理 " 栈帧 " , 栈帧 在 线程栈 中也是 后入先出 的 ; 每个栈帧都包含 局部变量表 , 操作数栈 , 动态链接 , 方法出口 , 这四个数据 ;

动态链接 : 每个 " 栈帧 " 都包含一个引用 , 是该引用指向 运行时 , 该 栈帧 对应方法 的引用 ;

局部变量表 : 存放 方法中的 局部变量 ;

操作数栈 : 存放方法执行中的 操作数 , 一般是 0 , 1 , 2 0,1 , 20,1,2 个数值 , 很少有其它情况 ;

方法出口 : 记录本方法执行完毕后该执行的下一行 JVM 指令 ;

本地方法栈 : 记录 JNI 执行的栈 ;

程序计数器 : 记录线程执行到哪一行的 JVM 指令 ;





二、垃圾回收机制


Java 中 不需要 手动回收 对象内存 , 由 Java 虚拟机 自动执行 ;


好处 : 开发相对简单 ;

坏处 : 不能直接操作内存 ;

C 语言中 , 自己 malloc 手动申请了内存 , 必须使用 free 手动释放内存 ;



垃圾回收 的目标 是 垃圾对象 , 主要针对 堆内存 中的空间进行 ;


垃圾对象 的判断标准 : 没有任何作用的 被废弃的 对象 , 即 一个对象 没有任何引用 指向它 ;






三、引用计数器算法 ( 无法解决循环引用问题 )


引用计数器算法 判定 垃圾对象 : 使用引用计数算法 , 判定一个对象是否是垃圾对象 ;


为 对象 分配 引用计数器 , 当 有一个引用指向它时 , 引用计数器 + 1 + 1+1 , 如果有 3 33 个引用指向该对象时 , 引用计数器值为 3 33 , 如果某个引用失效 , 则 引用计数器 − 1 - 1−1 , 如果对象的全部引用失效 , 则对象的引用计数器值为 0 00 , 此时该对象就是 垃圾对象 , 需要被回收 ;


目前成熟的 Java 虚拟机 没有使用 引用计数器 算法 , 因为 如果 两个对象 仅仅是 互相引用 , 这两个对象的引用计数器 都是 1 11 , 但是这两个对象与其余对象没有任何联系 , 这样就导致了 这两个对象所占用的内存 , 永久泄漏了 ;


引用计数器算法 无解解决 循环引用的问题 , 如果有 2 22 个及以上的对象循环引用 , 与程序隔绝 , 造成内存泄漏 , 无法解决 ;


目录
相关文章
|
1月前
|
负载均衡 NoSQL 算法
一天五道Java面试题----第十天(简述Redis事务实现--------->负载均衡算法、类型)
这篇文章是关于Java面试中Redis相关问题的笔记,包括Redis事务实现、集群方案、主从复制原理、CAP和BASE理论以及负载均衡算法和类型。
一天五道Java面试题----第十天(简述Redis事务实现--------->负载均衡算法、类型)
|
1月前
|
搜索推荐 算法 Java
手写快排:教你用Java写出高效排序算法!
快速排序(QuickSort)是经典的排序算法之一,基于分治思想,平均时间复杂度为O(n log n),广泛应用于各种场合。在这篇文章中,我们将手写一个Java版本的快速排序,从基础实现到优化策略,并逐步解析代码背后的逻辑。
61 1
|
28天前
|
设计模式 缓存 算法
揭秘策略模式:如何用Java设计模式轻松切换算法?
【8月更文挑战第30天】设计模式是解决软件开发中特定问题的可重用方案。其中,策略模式是一种常用的行为型模式,允许在运行时选择算法行为。它通过定义一系列可互换的算法来封装具体的实现,使算法的变化与客户端分离。例如,在电商系统中,可以通过定义 `DiscountStrategy` 接口和多种折扣策略类(如 `FidelityDiscount`、`BulkDiscount` 和 `NoDiscount`),在运行时动态切换不同的折扣逻辑。这样,`ShoppingCart` 类无需关心具体折扣计算细节,只需设置不同的策略即可实现灵活的价格计算,符合开闭原则并提高代码的可维护性和扩展性。
39 2
|
1月前
|
安全 算法 Java
java系列之~~网络通信安全 非对称加密算法的介绍说明
这篇文章介绍了非对称加密算法,包括其定义、加密解密过程、数字签名功能,以及与对称加密算法的比较,并解释了非对称加密在网络安全中的应用,特别是在公钥基础设施和信任网络中的重要性。
|
1月前
|
Java 数据安全/隐私保护 Windows
【Azure Developer】使用Java代码启动Azure VM(虚拟机)
【Azure Developer】使用Java代码启动Azure VM(虚拟机)
|
1月前
|
存储 Java API
【Azure Developer】通过Azure提供的Azue Java JDK 查询虚拟机的CPU使用率和内存使用率
【Azure Developer】通过Azure提供的Azue Java JDK 查询虚拟机的CPU使用率和内存使用率
|
1月前
|
数据采集 搜索推荐 算法
【高手进阶】Java排序算法:从零到精通——揭秘冒泡、快速、归并排序的原理与实战应用,让你的代码效率飙升!
【8月更文挑战第21天】Java排序算法是编程基础的重要部分,在算法设计与分析及实际开发中不可或缺。本文介绍内部排序算法,包括简单的冒泡排序及其逐步优化至高效的快速排序和稳定的归并排序,并提供了每种算法的Java实现示例。此外,还探讨了排序算法在电子商务、搜索引擎和数据分析等领域的广泛应用,帮助读者更好地理解和应用这些算法。
24 0
|
1月前
|
算法 Java 应用服务中间件
探索JVM垃圾回收算法:选择适合你应用的最佳GC策略
探索JVM垃圾回收算法:选择适合你应用的最佳GC策略
|
2天前
|
存储 缓存 Java
java线程内存模型底层实现原理
java线程内存模型底层实现原理
java线程内存模型底层实现原理
|
13天前
|
存储 缓存 安全
【Java面试题汇总】多线程、JUC、锁篇(2023版)
线程和进程的区别、CAS的ABA问题、AQS、哪些地方使用了CAS、怎么保证线程安全、线程同步方式、synchronized的用法及原理、Lock、volatile、线程的六个状态、ThreadLocal、线程通信方式、创建方式、两种创建线程池的方法、线程池设置合适的线程数、线程安全的集合?ConcurrentHashMap、JUC
【Java面试题汇总】多线程、JUC、锁篇(2023版)