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

Java 中的 GC -- GC基础常识

2019独角兽企业重金招聘Python工程师标准>>> hot3.png


文中讨论的GC原理均基于 Sun Hotspot JVM,对于不同 JVM 实现可能会有不同。


1. GC (Gabage Collector) 做了什么事情

  • 决定哪些内存需要回收(物理内存的位置)。

  • 决定何时回收这些内存。

  • 决定以什么方式(算法)回收这些内存

##2. GC 回收的不同区域

  • 堆内存(Heap)。
  • 方法区
  • 程序计数器,虚拟机栈,本地方法栈 随线程/方法 运行结束回收。
  • 堆外内存 GC 不负责回收。

##3. GC 回收对象 的依据 : 对象存活算法

  • 引用计数算法

    • 算法说明: 每个对象关联一个引用计数器,当有引用就加1,引用失效时减一,引用为0说明对象可回收
    • 缺陷: 对象循环互相引用不能检测,指的是,多个对象之间互相引用,但是这多个对象与其他外界不再具备任何访问条件的现象
  • 根搜索算法

    • 算法说明: 从一系列 GCRoot 对象向下搜索,搜索走过的路径叫做引用链,当某个对象不能通过引用链被搜索到,就说明可回收
    • GC Root: 1. 虚拟机栈中的引用对象 2. 方法区中静态变量引用的对象 3. 方法区常量池引用的对象 4. 本地方法栈中引用的对象 (JNI)
  • 总结

    • 大多数虚拟机采用的是跟搜索算法

##3. GC 引用的分类

  • 强引用

    • 说明: 使用 new 关键字实例化赋值的对象与变量之间的关系叫做强引用
    • 回收时机: 只要强引用存在,就永远不会被回收
  • 软引用

    • 说明: 描述有作用,但非必需的对象,使用 SoftReference 类来定义
    • 回收时机: 在系统发生内存溢出之前,会被纳入回收范围之内并进行第二次回收
  • 弱引用

    • 说明: 比软引用更弱的引用类型,使用 WeakReference 类来定义
    • 回收时机: 只能存活到下一次垃圾收集发生之前(无论时候内存溢出)
  • 虚引用

    • 说明: 最弱的引用类型,虚引用相当于对象的生命周期是透明的(不会延长对象的生命周期),甚至无法通过虚引用获得对象的实例,唯一的目的就是在被回收的时候收到一个系统通知,使用 PhantomReference 类来定义
    • 回收时机: 相当于不存在,不影响回收时机

##3. GC 回收对象的全过程

  • 堆内存的回收

    • 回收特点: 堆内存主要回收废弃,无用的对象
    • 回收过程:
      1. 根据存活算法扫描到某个对象A已经不被引用并进行第一次标记
      2. 第一次标记之后,筛选该对象是否有必要执行 finalize() 方法,执行的条件是该对象覆盖了finalize() 方法,并且finalize() 方法未被调用过。
      3. 如果没有必要执行finalize() 方法
      4. 如果有必要执行finalize()方法,该对象被放置到一个F-QUEUE队列中,并在一个虚拟机线程去执行,执行的过程中,只保证触发这个方法,不保证等待方法运行结束(防止时间过长、死循环 导致GC回收机制崩溃)
      5. GC 进行第二次扫描,如果发现再次发现对象A 不被引用,那么就将执行回收过程;这里如果对象A在步骤 4 中执行finalize() 方法的时候,在代码里面重新与GCRoot引用链获得的访问关系,这次扫描将不会被扫描到,但是因为finalize()已经被执行过了,所以下次一旦被扫描到,就不能再通过finalize()来GC逃逸了
  • 方法区内存的回收

    • 回收特点: 方法区内存主要回收废弃,不用的 常量,类,接口

    • 回收常量: 加入对于某个常量池中的字符串,已经没有任何该类型(String)的对象是这个值,也没有其他地方引用到了这个字面量,如果这个时候发生内存回收,而且有必要(这个根据情具体实现况判断什么是有必要,比如常量的生命时间,常量的使用频率等),这个常量将被回收

    -回收类(包括它的接口,方法名,字段): 1. 该类的实例对象都已经被回收 2. 加载该类的ClassLoader也已经被回收 3. 该类的Class 对象没有被任何地方引用,也就是无法通过反射来访问这个类 4. 当满足了上述3个条件,仅仅是说明可以回收了,不代表会回收,具体看不同虚拟机的限定条件 5. 类回收的主要场景: 对于应用大量 反射,动态代理,CGLib 等bytecode的框架以及场景,动态生成JSP和OSGI等频繁定义用户ClassLoader的场景,都有可能产生大量的自动生成的类加载行为,为了防止永久区溢出,需要对这种生成的类进行卸载

转载于:https://my.oschina.net/samuelzuuka/blog/739891

相关文章:

  • 五分钟搞定 HTTPS 配置,二哥手把手教
  • 5 Maven生命周期和插件
  • 坦克大战--Java类型 ---- (2)按键设置和用户名的输入
  • Ubuntu SSH root 登录 Permission denied 错误
  • nginx版本升级问题
  • 每天学习2小时,17年前端经验分享,让你前端之路不再迷茫
  • CSS background 属性
  • 节日营销!这样搞-App运营日常
  • CodeForces 709C Letters Cyclic Shift
  • IT兄弟连 Java Web教程 Tomcat
  • C语言之goto浅析
  • chromedriver设置下载路径
  • 51nod 1364 最大字典序排列(线段树)
  • 微信公众号无法使用css3的多行省略
  • 内网无路由跨网络服务——单网卡双IP配置
  • docker-consul
  • GDB 调试 Mysql 实战(三)优先队列排序算法中的行记录长度统计是怎么来的(上)...
  • JS实现简单的MVC模式开发小游戏
  • React的组件模式
  • RxJS: 简单入门
  • SQL 难点解决:记录的引用
  • vue.js框架原理浅析
  • 初探 Vue 生命周期和钩子函数
  • 大数据与云计算学习:数据分析(二)
  • 码农张的Bug人生 - 初来乍到
  • 巧用 TypeScript (一)
  • 新版博客前端前瞻
  • 原生 js 实现移动端 Touch 滑动反弹
  • 原生JS动态加载JS、CSS文件及代码脚本
  • 在Unity中实现一个简单的消息管理器
  • 在weex里面使用chart图表
  • Nginx惊现漏洞 百万网站面临“拖库”风险
  • 仓管云——企业云erp功能有哪些?
  • #每日一题合集#牛客JZ23-JZ33
  • $.each()与$(selector).each()
  • (1)Map集合 (2)异常机制 (3)File类 (4)I/O流
  • (android 地图实战开发)3 在地图上显示当前位置和自定义银行位置
  • (Mirage系列之二)VMware Horizon Mirage的经典用户用例及真实案例分析
  • (Python) SOAP Web Service (HTTP POST)
  • (Redis使用系列) SpringBoot 中对应2.0.x版本的Redis配置 一
  • (非本人原创)我们工作到底是为了什么?​——HP大中华区总裁孙振耀退休感言(r4笔记第60天)...
  • (附源码)计算机毕业设计SSM智慧停车系统
  • (三十五)大数据实战——Superset可视化平台搭建
  • (转)EXC_BREAKPOINT僵尸错误
  • (转)Linux NTP配置详解 (Network Time Protocol)
  • (转载)CentOS查看系统信息|CentOS查看命令
  • .NET Compact Framework 多线程环境下的UI异步刷新
  • .Net core 6.0 升8.0
  • .NET delegate 委托 、 Event 事件
  • .NET 设计模式—简单工厂(Simple Factory Pattern)
  • .NET 药厂业务系统 CPU爆高分析
  • .NET/C# 获取一个正在运行的进程的命令行参数
  • .NET/C# 利用 Walterlv.WeakEvents 高性能地定义和使用弱事件
  • .net反编译工具
  • .Net开发笔记(二十)创建一个需要授权的第三方组件