java面试一日一题:如何判断一个对象是否为垃圾对象
问题:请讲下在java中如何判断一个对象是否为垃圾
分析:该问题主要考察对java中的垃圾回收,用什么方式去识别一个对象是垃圾;
回答要点:
主要从以下几点去考虑,
1、GC回收的是什么,回收发生在内存的那部分?
2、怎么判断一个对象是否可以被回收?
3、垃圾回收的算法有哪些?
都说C/C++语言难学,难的点其实不是语言本身,而是在内存管理方面,因为在C/C++中需要开发者自己管理内存,包括申请内存和释放内存,不恰当的释放内存经常导致程序崩溃,而在java中开发者却不需要关心何时释放内存。很多人认为java没有内存管理的概念,其实不是这样的,只不过java虚拟机帮我们做了,那就是垃圾回收,简称GC。
所谓GC就是要回收java程序允许过程中产生的垃圾,也可以理解为不再使用的内存,一个程序的内存是有限的,随着程序的运行,肯定存在申请内存的情况,如果使用完内存迟迟得不到释放,那么程序最终会因为没有内存而停止,所以内存的释放很重要。在面向对象程序中内存的释放意味着对象的销毁,只有对象销毁了内存才有可能得以释放,内存才至于枯竭。
上面明白了为什么要有GC,GC的目的就是为了释放内存,使程序可以持续运行。在java中程序运行时的内存区域可分为堆、虚拟机栈、本地方法栈、程序计数器、方法区。GC回收的区域是堆和方法区,为什么回收这两个区域那,因为他们是线程共享的,即java程序中所有的线程都可以访问,在这两部分中回收的重点在堆,方法区一般回收起来很困难,下面的介绍均是指堆方法区的垃圾回收。为什么虚拟机栈、本地方法栈、程序计数器没有GC,因为他们是线程私有的,随着线程的消亡而消亡。
从网上找了一张运行时内存区域的图,
该图很形象的说明了java运行时数据区的每个部分,当然是逻辑划分而不是物理划分。
现在,弄清楚了GC要回收的内存区域是堆,堆中存放的是对象,在java的世界中万事万物都是对象,归根结底要回收的是堆中的对象。那如何确定什么对象是可回收的什么对象是不可回收的。java提供了两种算法,引用计数法和可达性分析法。java中使用的是可达性分析法
引用计数法
所谓引用计数法,每个对象额外保存一个计数属性,如果有一个对象引用了它,那么该属性会加1,例,
A a=new A();
A a2=a;
上面这段代码会在堆中生成一个A的对象实例,且a、a2都指向了该对象,那么该对象的计数属性便是2,又如,
A a=new A();
A a2=a;
a=null;
a2=null;
这时a、a2均指向了null,那么A的对象实例的计数属性则为0,按照引用计数法的定义这时该实例可以被回收。
看上去该算法很完美,但是java中为什么没用,有个问题如果出现循环引用怎么办,
A a=new A();
B b=new B(); a.b=b;
b.a=a; a=null;
b=null;
上面的代码在堆中会有一个A的实例一个B的实例,且计数属性均为1,执行了第3、4两行代码后,两个实例的引用计数均为2,执行了5、6两行代码后两个实例的计数属性均为1,这时a、b均指向了null,但是堆中的两个实例的计数属性的值却不为0,那么这两个实例无法回收,存在内存泄漏的风险;
可达性分析法
所谓可达性分析法,就是从一些称为引用链(GC ROOTS)的对象作为起点,从这些节点向下搜索,搜索走过的路径称为引用链(reference chain),当一个对象到GC ROOTS没有引用链的时则该对象不可达,该对象可以被回收。哪些对象是引用链那,虚拟机栈是java程序中方法执行的区域,每个方法的执行对应着一个栈帧的入栈和出栈,方法执行完了其申请的内存便可以释放,所以栈帧中的对象可作为引用链对象,同时本地方法栈的情况也是类似的;在方法区中存在常量和类静态变量,这两种变量也可以作为引用链对象,总结下来有下面几种,
1、虚拟机栈中的局部变量表中的对象;
2、方法区中常量引用的对象;
3、方法区中类的静态变量引用的对象;
4、本地方法栈中JNI引用的对象;
使用可达性分析方法判断为可回收的对象,还有一次逃过回收的机会,那就是在Object类中有finalize()方法,如果在该方法中没有与上述的引用链建立链接,那么该对象则确定要被回收。
知道了要回收的内存区域,以及如何判定哪些对象可以被回收,确定了回收对象,接下来就是如何回收,且听下次分解。
参考:https://www.cnblogs.com/czwbig/p/11127124.html
java面试一日一题:如何判断一个对象是否为垃圾对象的更多相关文章
- java面试一日一题:如何设计一款垃圾回收器
问题:如果让你设计一个垃圾回收器,你会考虑哪些问题 分析:该问题主要考察对java中垃圾回收器的理解,要理解怎么回收:一款好的垃圾回收器有哪些衡量指标 回答要点: 主要从以下几点去考虑, 1.垃圾回收 ...
- java面试一日一题:java中的垃圾回收器
问题:请讲下java中垃圾回收器有哪些? 分析:该问题主要考察hotspot虚拟机下实现的垃圾回收器 回答要点: 主要从以下几点去考虑, 1.垃圾回收器的种类 2.每种垃圾回收器的着重点是什么 前边的 ...
- java面试一日一题:java中垃圾回收算法有哪些
问题:请讲下在java中有哪些垃圾回收算法 分析:该问题主要考察对java中垃圾回收的算法以及使用场景 回答要点: 主要从以下几点去考虑, 1.GC回收算法有哪些 2.每种算法的使用场景 3.基于垃圾 ...
- java面试一日一题:讲下在什么情况下会发生类加载
问题:请讲下在什么情况下会发生类加载? 分析:该问题主要考察对java中类加载的知识,什么是类加载,为什么会发生类加载,什么情况下发生类加载? 回答要点: 主要从以下几点去考虑 1.什么是类加载: 2 ...
- java面试一日一题:mysql中常用的存储引擎有哪些?
问题:请讲下mysql中常用的引擎有哪些? 分析:该问题主要考察对mysql存储引擎的理解,及区别是什么? 回答要点: 主要从以下几点去考虑, 1.mysql的存储引擎的基本概念? 2.mysql中常 ...
- java面试一日一题:讲下mysql中的undolog
问题:请讲下mysql中undo log的作用 分析:mysql中有很多日志,例,bin log undo log redo log,要弄清楚这些日志的作用,就要了解这些日志出现的背景及要解决的问题: ...
- java面试一日一题:java中一个对象实例的结构是什么样子的
问题:请讲下在java程序运行时一个对象实例的数据结构是什么样子的 分析:该问题主要考察对java中对象的理解,在程序运行过程中一个对象实例是以什么样的形式存在的 回答要点: 主要从以下几点去考虑, ...
- java面试一日一题:java线程池
问题:请讲下java中的线程池 分析:在面试中经常问到线程池的问题,要掌握其基本概念,使用方法,注意事项等,引申下tomcat中默认的线程数是多少 回答要点: 主要从以下几点去考虑, 1.为什么要使用 ...
- java面试一日一题:讲对mysql的MVCC的理解
问题:请讲下对mysql中MVCC的理解 分析:这个问题要回答的是对MVCC的理解,以及MVCC解决了什么问题这几个方面入手. 回答要点: 主要从以下几点去考虑, 1.什么是MVCC? 2.MVCC用 ...
随机推荐
- 关于Java中Collections.sort和Arrays.sort的稳定性问题
一 问题的提出 关于Java中Collections.sort和Arrays.sort的使用,需要注意的是,在本文中,比较的只有Collections.sort(List<T> ele ...
- IPFS挖矿硬盘满了会怎样?
IPFS是一个互联网协议,对标现在的HTTP.所以,可以想见未来IPFS有多大的价值.所谓IPFS挖矿,是基于IPFS,挖的是filecoin,称其为filecoin挖矿倒是更为贴切.许多初接触IPF ...
- PTA 两个有序链表序列的合并
6-5 两个有序链表序列的合并 (15 分) 本题要求实现一个函数,将两个链表表示的递增整数序列合并为一个非递减的整数序列. 函数接口定义: List Merge( List L1, List L ...
- python3 输出字符
import string'''whitespace -- a string containing all ASCII whitespaceascii_lowercase -- a string co ...
- Android学习之Broadcast初体验
•何为 Broadcast ? Broadcast 直译广播,接下来举个形象的例子来理解下 Broadcast: 上学的时候,每个班级都会有一个挂在墙上的大喇叭,用来广播一些通知,比如,开学要去搬书, ...
- PAT (Advanced Level) Practice 1046 Shortest Distance (20 分) 凌宸1642
PAT (Advanced Level) Practice 1046 Shortest Distance (20 分) 凌宸1642 题目描述: The task is really simple: ...
- Docker遇到的异常和注意点
Docker遇到的异常和注意点 整理一些使用docker的时候,遇到的问题和解决办法 遇到的一些异常和解决方法 删除镜像时出现: Error response from daemon: conflic ...
- Ubuntu安装docker/docker-compose(在全新系统状态下的安装)
设置仓库 更新 apt 包索引. $ sudo apt-get update 安装 apt 依赖包,用于通过HTTPS来获取仓库: $ sudo apt-get install \ apt-trans ...
- 一文简述Java IO
Java IO 本文记录了在学习Java IO过程中的知识点,用于复习和快速查阅,不够详细的部分可能会在后续补充. 什么是流 流:内存与存储设备(外存)之间传输数据的通道 IO:输入流输出流(如rea ...
- [开源]制作docker镜像不依赖linux和Docker环境
背景 最近群友们经常反馈docker镜像制作起来有点麻烦,我开源的antdeploy工具虽然可以制作镜像但是必须有一个提前:有一台安装好docker的linux服务器.因为大家开发环境基本上都是win ...