众所周知,在java语言中,内存分配和回收是由jvm自动管理的。因此内存的分配和回收也是jvm三大功能之一。垃圾收集器(GC)需要完成三件事情:

  • 哪些内存需要回收?
  • 什么时候进行回收?
  • 如何回收?

    本篇博客将解答jvm是如何处理以上三个问题的。值得注意的是,java运行时数据区中的程序计数器,虚拟机栈,本地方法栈三个区域随线程而生,随线程而灭,栈中的栈帧随着方法的进入和退出而有条不紊地执行进栈和出栈的操作,每一个栈帧分配多少内存基本上是在类结构确定下来的时候就已知的。因此以上三个区域不需要过多考虑回收的问题,因为在线程或者方法结束时,内存自然就跟着回收了。垃圾收集器更加关注堆内存的分配和回收,因为堆中内存的分配和回收都是动态的,是在程序运行时才能确定的。

如何判断对象已死?(哪些对象需要被回收?)

目前有两种方法判断对象是否存活。由于引用计数法无法解决循环引用的问题,因此java虚拟机中使用的是可达性分析法。

  1. 引用技术法(了解)

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

    引用计数法的优点:实现简单,判定效率高

    缺陷:无法解决循环引用问题
  2. 可达性分析法

    通过一系列的称为“GC Roots”对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链,当一个对象到GC Roots没有任何引用链的时候,(用途论的话来说,就是从GC Roots到这个对象不可达的时候)。则证明此对象是不可用的。

    可作为GC Roots的对象包括:
  • 虚拟机栈(栈帧中的本地变量表)中所引用的对象。

  • 方法区中静态属性引用的对象

  • 方法区中常量引用的对象

  • 本地方法区中JNI(即一般说的Native方法)所引用的对象

    因为以上四种类型都可能持有对堆中对象的引用。因此这四种都可以作为GC Roots

java中的四种引用(以下内容回答对象何时被回收的问题)

我们希望有这样一种对象:当内存空间还足够时,将其保留在内存空间之中,如果内存空间在进行垃圾收集之后还是非常紧张,就抛弃这些对象。因此我们需要扩充java中引用的概念:

强引用:一般引用,类似Object obj = new Object()。只要强引用还存在,就不会回收掉被引用的对象。

软引用:

最新文章

  1. android studio sdk 不能更新
  2. YUV和RGB格式分析
  3. linux更改shell
  4. php笔记之GD库图片创建/简单验证码
  5. 刷爆github小绿点
  6. BZOJ 1597: [Usaco2008 Mar]土地购买( dp + 斜率优化 )
  7. PL/SQL Developer ORA-12154: TNS: 无法解析指定的连接标识符
  8. 使用assets目录来实现插件机制
  9. 在VCS仿真器中使用FSDB
  10. SQLServer之事务简介
  11. js计算两个日期的月份差?
  12. python常用的基本操作
  13. kibana Dev tool 查询结果与预期不符
  14. python 安装 reportlab 报错 “ImportError: No module named reportlab.lib”
  15. spark单击 搭建
  16. C++内存分区:堆、栈、自由存储区、全局/静态存储区和常量存储区
  17. Linux命令(九)查找文件find
  18. python2和python3的区别总结
  19. (转)CloudStack 安装及使用过程中常见问题汇总
  20. CCF CSP 201609-3 炉石传说

热门文章

  1. 【Golang】vscode 设置 go 开发环境
  2. 腾讯开源 APIJSON 连创五个第一
  3. mvc SelectList 给下拉框 @Html.DropDownList绑定值
  4. Hopfield Network 霍普菲尔德网络入门
  5. 基于云开发 CloudBase 搭建在线视频会议应用教程
  6. 工具博客转载-ftrace
  7. JsonPath在接口自动化中的应用
  8. 论文学习笔记 - 高光谱 和 LiDAR 融合分类合集
  9. 手写一个最迷你的Web服务器
  10. 预估Ceph集群恢复时间