java识别死亡或者存活的对象
那些内存需要回收
内存回收是对运行时内存区域的内存回收,其中程序计数器、虚拟机栈、本地方法栈3个区域随线程而生,随线程而灭;栈中的栈帧随着方法的进入和退出而有条不紊的执行着出栈和入栈操作。每一个栈帧中分配多少内存基本上是在类结构确定下来就已知的,因此这几个区域的内存分配和回收都具备确定性,在这几个区域就不需要过多考虑回收的问题,因为方法结束或者线程结束时,内存自然就跟随着回收了。
而Java堆和方法区则不一样,一个接口中的多个实现类需要的内存可能不一样,一个方法的多个分支需要的内存可能也不一样,我们只有在程序运行时才知道会创建哪个对象,这部分内存的分配和回收都是动态的,垃圾收集器需要回收的内存就这堆上的内存。
哪些对象已死?哪些对象还活着
Java垃圾收集器在进行内存回收的时候,需要对内存进行判别,判断他是活着的还是已死的,即是可回收的还是不可回收的,下面是判断对象存活与否的方法。
引用计数算法
给对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加一;当引用失效时,计数器值就减一;任何时刻计数器为0的对象就是不可能再被使用的。但是它很难解决对象间相互循环引用的问题。
可达性分析算法
在主流的商用语言(Java,c#, lisp)中是通过可达性分析算法来判断对象是否存活的。这个算法的基本思路就是通过一系列的称为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索搜走过的路径称为引用链(Reference Chain),当一个对象到GC Roots没有任何引用链相连时,则证明对象是不可用的。
在Java语言中,可作为GC Roots的对象包括下面几种
- 虚拟机栈(栈帧中的本地变量表)中引用的对象
- 方法区中类静态属性引用的对象
- 方法区中常量引用的对象
- 本地方法栈中JNI(即一般说的native方法)引用的对象
引用探索
在java1.2以前,java中的引用的定义很传统:如果reference类型的数据中存储的是另一块内存的起始地址,就称这块内存代表着一个引用;这种定义很纯粹,但是太过于狭隘,一个对象在这种定义下只有被引用和没有被引用两种状态,对于表示一些"食之无味,弃之可惜"的对象就显得无能为力;其实我们希望还能描述其他的一些状况:当内存空间还足够时,则留在内存空间中;如果内存空间进行垃圾收集以后还是很紧张,则可以抛弃这些对象,于是我们这些对象的引用分为4个等级,4中引用强度一次削弱;
- 强引用:强引用在程序代码中是普遍存在的,类似“Object o = new Object()”,只要强引用还在,垃圾回收器永远不会回收这类被引用的对象;
- 软引用:软引用是用来描述一些还有用但是非必须的对象。对于软引用的对象,在系统将要发生内存溢出异常之前,将会把这些对象列入回收范围内进行第二次回收。如果系统回收后还是没有足够的内存,系统将会抛出内存溢出异常,jdk1.3以后提供了SotfReference类来实现软异常。
- 弱引用:弱引用也是用来描述一些非必须的对象,但是它的强度比软引用还要弱一点,被弱引用关联的对象只能生存到下一次垃圾收集器之前。jdk1.2之后提供了WeakReference类实现弱引用
- 虚引用:目的就是能在对象被收集器回收之前收到一个系统通知。jdk1.2后提供了PhantonReference类来实现虚引用。
java识别死亡或者存活的对象的更多相关文章
- Java虚拟机:如何判定哪些对象可回收?
版权声明:本文为博主原创文章,转载请注明出处,欢迎交流学习! 在堆内存中存放着Java程序中几乎所有的对象实例,堆内存的容量是有限的,Java虚拟机会对堆内存进行管理,回收已经"死去&quo ...
- Effective Java笔记一 创建和销毁对象
Effective Java笔记一 创建和销毁对象 第1条 考虑用静态工厂方法代替构造器 第2条 遇到多个构造器参数时要考虑用构建器 第3条 用私有构造器或者枚举类型强化Singleton属性 第4条 ...
- 《java JDK7 学习笔记》之对象封装
1.构造函数实现对象初始化流程的封装.方法封装了操作对象的流程.java中还可以使用private封装对象私有数据成员.封装的目的主要就是隐藏对象细节,将对象当做黑箱子进行操作. 2.在java命名规 ...
- [Effective Java]第二章 创建和销毁对象
声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...
- JAVA之等号、传类对象参数与c++的区别
在JAVA中用等号对类对象进行赋值,实际上操作的是对象的地址. eg: package MyText; class ClassA { int value; public void seta(int v ...
- java class加载机制及对象生成机制
java class加载机制及对象生成机制 当使用到某个类,但该类还未初始化,未加载到内存中时会经历类加载.链接.初始化三个步骤完成类的初始化.需要注意的是类的初始化和链接的顺序有可能是互换的. Cl ...
- 【Java基础】Java类的加载和对象创建流程的详细分析
相信我们在面试Java的时候总会有一些公司要做笔试题目的,而Java类的加载和对象创建流程的知识点也是常见的题目之一.接下来通过实例详细的分析一下. 实例问题 实例代码 Parent类 package ...
- Java类的加载和对象创建流程的详细分析
相信我们在面试Java的时候总会有一些公司要做笔试题目的,而Java类的加载和对象创建流程的知识点也是常见的题目之一.接下来通过实例详细的分析一下: package com.test; public ...
- java中集合Collection转list对象
参考:java中集合Collection转list对象 首先我的需求是获取到购物车列表,购物车列表是一个Map对象,构造方法获取购物项,这里购物项是Collection对象 // 购物项集合,K商品I ...
随机推荐
- Flask--g属性
目录 Flask之g属性 使用 session,flash,g的区别 Flask之g属性 专门用来存储用户信息的g对象,g的全称的为global g对象在一次请求中的所有的代码的地方,都是可以使用的 ...
- chrome安装react-devtools开发工具
我开始安装react-devtools的时候 百度了一波,都是写的不清不楚,官网又都是英文的 也不是完全理解,经过一番折腾出来以后,写个文档记录一下,也可避免新手首次安装走弯路 我安装react-de ...
- 【原】通过Spring结合Cglib处理非接口代理
前言: 之前做的一个项目,虽然是查询ES,但内部有大量的逻辑计算,非常耗时,而且经常收到JVM峰值告警邮件.分析了一下基础数据每天凌晨更新一次,但查询和计算其实在第一次之后就可以写入缓存,这样后面直接 ...
- Android软件架构
08_29_Android软件架构 架构的本质 本质, 类似图纸, 不是建筑物: 明确范围 软件设计中, 架构不等于框架: 底层的编码,到设计模式, 到框架,再到架构(微服务,SOA) 好的架构 做好 ...
- 实用的生成二维码API
推荐一个生成二维码的API网站: 中文 http://www.topscan.com 英文 https://api.qrserver.com/v1/create-qr-code/?size=150x1 ...
- HBase常用的JAVA API操作
为了方便以后查看,总结了一些常用的java操作hbase的代码: package com.mcq; import static org.hamcrest.CoreMatchers.describedA ...
- 前台VUE的组件之间传参方式
路由传参 """ 转跳: <router-link :to="'/course/'+course.id">{{course.name}}& ...
- linux 进程通信之 mmap
一,管道PIPE 二,FIFO通信 三,mmap通信 创建内存映射区. #include <sys/mman.h> void *mmap(void *addr, size_t length ...
- Placeholder_2:0 is both fed and fetched
Placeholder_2:0 is both fed and fetched TensorFlow出现这个错误是因为网络的输入被原样输出,也就是说同一个东西既被输入网络,又被输出网络.
- poi基本使用
poi基本使用 依赖 <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi< ...