java中对象的生存期_深入理解Java虚拟机-判断对象是否存活算法与对象引用

我们知道Java中的对象一般存放在堆中,但是总不能让这些对象一直占着内存空间,这些对象最终都会被回收并释放内存,那么我们如何判断对象已经成为垃圾呢?这篇文章会提出两种算法解决这个问题。另外,本文还要谈一谈对象引用相关的知识,这在面试中也是经常被问到的问题。

判断对象是否存活算法

引用计数算法

引用计数算法的原理比较简单,在对象中添加一个引用计数器,当有一个引用指向一个对象时,这个对象的引用计数器会加1,当引用不再指向对象时,引用计数器便减1。当引用计数器的值为0时,说明对象已经成为垃圾。

引用计数算法的优点是算法非常简单,效率也比较高。但是Java并没有使用这种算法管理内存,这是为什么呢?我们先来看看下面这段代码。

public class Demo {

public static void main(String[] args) {

Obj obj1 = new Obj();

Obj obj2 = new Obj();

obj1.instance = obj2;

obj2.instance = obj1;

obj1 = null;

obj2 = null;

}

}

class Obj {

public Obj instance;

public Obj() {

super();

}

}

我们看一下上面这段代码,两个对象obj1和obj2的instance分别指向对方,造成了循环引用。即便最后obj1和obj2都置为空,但它们的instance还是指向对方,如果我们使用这种算法,这两个对象势必无法回收,最终造成内存泄漏。因此,Java没有选择使用引用计数算法管理内存。

可达性分析算法(根搜索算法)

主流的商用编程语言(Java、C#以及上古语言Lisp)都是用这种算法进行对象是否存活的判断。

根搜索算法利用GC Roots作为起始节点集,从这些节点开始向下搜索,凡是能够到达的节点都是存活节点,不能到达的节点都不再会被使用,这些节点的对象都可以被回收。

Java技术体系中可以作为GC Roots的对象有以下几种:虚拟机栈(栈帧的本地变量表)中引用的对象

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

方法区中常量引用的对象

本地方法栈中JNI(及native方法)引用的对象

虚拟机内部的引用,比如基本数据类型对应的Class对象,一些常驻的异常对象(如NullPointerException、OutOfMemoryError)等,还有类加载器。

被同步锁(synchronized)持有的对象

反映Java虚拟机内部情况的JMXBean、JVMTI注册的回调,本地代码缓存等

另外,需要补充的是,即便被可达性分析算法标记为不可达对象,这些对象也未必一定会被回收。事实上,被标记为不可达对象后,这个对象还需要经历第二次标记才可能会被宣布正式死亡。当第一次标记以后,会判断对象有没有必要执行finalize()方法。当对象没有覆盖finalize()方法或已经被虚拟机调用过的话,就被判定没有必要再继续执行了。当有必要执行finalize()方法时,这些对象会被放在名为F-Queue的队列中,随后虚拟机会创建一个线程去执行队列中的对象的finalize()方法。如果这些对象在收集器对F-Queue中对象标记前在finalize()方法中重新与引用链上的对象建立关系,比如将自己赋值给某个类变量就可以移出回收集合,免除被回收的命运。

对象引用

谈到引用,不得不提到前几天的考研复试,我的一位学弟在复试过程中被问到Java中有哪些引用,这几种引用有什么区别。被问到这道题时,他一时语塞,没有回答上来。不过好在没有因为这道题受到影响。今天我们就来谈一谈Java中的四种引用。强引用。强引用是我们平时使用最多的引用方法。Object obj = new Object()这就是一个典型的强引用实例,只要强引用关系还存在,即使系统内存不足,也不会回收这些对象。

软引用。软引用用来描述一些还有用,但不是必须的对象,使用SoftReference类来实现软引用。当系统内存不足时,会回收软引用关联的对象。

弱引用。弱引用通过WeakReference类来实现,即使内存充足,下一次垃圾收集时,弱引用对象也会被回收。

虚引用。虚引用又称“幽灵引用”或“幻影引用”,是最弱的一种对象引用,它使用PhantomReference类来实现。虚引用的作用是在关联的对象被回收时能收到一个系统通知。

喜欢的给个赞呗

了解更多可以关注我的公众号:SKY技术修炼指南

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/397016.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

大数据高效复制的处理案例分析总结

一个老客户提出这样的需求,希望将SQLServer中的某个表的数据快速复制到SQLite数据库里面以便进行定期的备份处理,数据表的记录大概有50多万条记录,表有100个字段左右,除了希望能够快速做好外,效率是第一位的&#xff0…

@autowired注解注入为null_Intellij IDEA中Mybatis Mapper自动注入警告的6种解决方案

相信使用Mybaits的小伙伴们一定会经常编写类似如下的代码:可以看到 userMapper 下有个红色警告。虽然代码本身并没有问题,能正常运行,但有个警告总归有点恶心。本文分析原因,并列出解决该警告的几种方案。原因众所周知&#xff0c…

五 Python之socket网络编程

<1>socket概念 socket通常也称作"套接字"&#xff0c;用于描述IP地址和端口&#xff0c;是一个通信链的句柄&#xff0c;应用程序通常通过"套接字"向网络发出请求或者应答网络请求。ocket本质上就是在2台网络互通的电脑之间&#xff0c;架设一个通道…

致敬2016,拥抱2017

2016年5月10号加入现在的团队&#xff0c;到今天2016年12月31号&#xff0c;已经过去了接近8个月。这整个期间&#xff0c;我们团队都只有我一个前端工程师&#xff0c;我从刚开始的忐忑不安、压力极大&#xff0c;到现在基本上手&#xff0c;我们团队做的项目虽然不大&#xf…

你如何在java中获取线程堆_如何在Windows上获取未在控制台中运行的Java进程的线程和堆转储...

问题我有一个Java应用程序&#xff0c;我从控制台运行&#xff0c;然后控制台执行另一个Java进程。我想获得该子进程的线程/堆转储。在Unix上&#xff0c;我可以做akill -3 但是在Windows AFAIK上获取线程转储的唯一方法是在控制台中使用Ctrl-Break。但这只会让我转移父进程&am…

html ie乱码_Java 0基础入门(初识Html)

在学习Java之前&#xff0c;我们需要了解一定的前端知识。毕竟页面才是用户真正看到的&#xff0c;而且也是体现Java后端逻辑结果的地方。学习HTML后&#xff0c;能够制作界面美观大方的静态网站(更复杂的功能需要JavaScript脚本一起来实现)。HTML制作的网页。所需要的Html开发…

常用自动化框架简单的分析与介绍

目前常用的可用于APP自动化测试的框架有以下几个&#xff1a; 1、Monkey是Android SDK自带的测试工具&#xff0c;在测试过程中会向系统发送伪随机的用户事件流&#xff0c;如按键输入、触摸屏输入、手势输入等)&#xff0c;实现对正在开发的应用程序进行压力测试&#xff0c;也…

linux一步一脚印---more、less、head、tail

一、more 文件内容或输出查看命令more 是我们最常用的工具之一&#xff0c;最常用的就是显示输出的内容&#xff0c;然后根据窗口的大小进行分页显示&#xff0c;然后还能提示文件的百分比&#xff1b; [rootlocalhost ~]# more /etc/profile 1、more 的语法、参数和命令&#…

单片机检测stc没反应_我为什么不用STC单片机

写在2019.10.27这属于自己打自己脸&#xff0c;不过&#xff0c;我突然想试试 STC15W108.理由可能有点操蛋&#xff0c;因为STM8S没有 DFN8这样 3x3的封装&#xff0c;而PIC的仿真器太贵。我最后感兴趣的一个STC型号是 STC15F的8脚系列&#xff0c;那是在2010年&#xff0c;然而…

commons-pool

commons-pool组件是使用对象池时都要用到的。他的作用主要是管理对象池&#xff0c; 当我们要用这个组件时&#xff08;比如redis要用到时&#xff09;&#xff0c;只需要实现它的部分接口&#xff0c;比如PooledObjectFactory接口&#xff0c;实现它的创建对象&#xff0c;销毁…

JAVA中CyclLink怎么用_Java多线程基本使用一

1 多线程--初步【1进程比如&#xff1a;QQ、迅雷、360、飞秋...2线程的概念3线程的意义&#xff1a;4.Java程序的运行原理代码是运行在线程中的&#xff0c;如果一个进程没有线程&#xff0c;那么进程就结束了&#xff0c;也就是说一个进程至少要有一个线程当开启一个Java…

指针分析

int *a; int b 4; a &b; //a:b的地址 //*a 取b地址的值&#xff0c;为4 //&a为指针变量的地址 //*(&a)为指针变量储存的地址 即为a int **b &a; //b为指针变量a的地址 //*b为指针变量a所储存的地址 //改变*b(指针变量所储存的地址)即改变了*b的值转载于:http…

live server插件怎么用_分享几个我日常使用的VS Code插件

在这篇文章中&#xff0c;我想介绍一下自己日常使用中最喜欢的Visual Studio Code扩展。大多数时候&#xff0c;我用VS Code编写的是JavaScript应用程序(标准JavaScript、React、Angular、NodeJS……各式各样)。Bracket Pair Colorizer 2这个扩展很不错&#xff0c;可以帮助我搞…

Xtrabackup数据全备份与快速搭建从服务器

Percona Xtrabackup可以说是一个完美的数据备份工具。特别是当数据库的容量达到了一定数量级的时候且存在单表达到几十G的数据量&#xff0c; 很难容忍一些逻辑备份的漫长时间。如单个数据库约200G&#xff0c;单表最大为120G&#xff0c;mysqldump逻辑备份的时间长达20多小时。…

简单的java方法_Java简单实用方法一

整理以前的笔记&#xff0c;在学习Java时候,经常会用到一些方法。虽然简单但是经常使用。因此做成笔记&#xff0c;方便以后查阅这篇博文先说明构造和使用这些方法。1&#xff0c;判断String类型数据是否为空String类型的数据为空&#xff0c;主要为等于null或”“那么只要判断…

Android应用程序开发

第一章 Android应用初体验 1.1应用基础 activity是Android SDK中Activity类的一个具体实例&#xff0c;负责管理用户与信息屏的交互。 应用的功能是通过编写一个个Activity子类来实现的。 布局定义了一系列用户界面对象以及它们显示在屏幕上的位置。组成布局的定义保存在XML文件…

phonegap

phonegap 框架详解 转自&#xff1a;http://www.cnblogs.com/hubcarl/p/4216844.html首先, 来看一下phonegap 初始化流程以及Native 与 JS 交互流程图。 说明&#xff1a;socket server模式下, phonegap.js 源码实现的采用1 毫秒执行一次XHR请求, 当Native JS 队列里面有JS语…

j2ee核心模式_Operator和Sidecar正在成为软件交付新模式

现如今的开发人员希望可以开发出具备弹性和可扩展的分布式系统。该系统受益于软件复用和开源模型创新&#xff0c;针对安全性问题能够轻易完成补丁更新并进行低风险的升级。该系统不可能通过带有各种嵌入式语言库的应用程序框架来实现。最近&#xff0c;一篇关于“多运行时微服…

微信JS-SDK选择相册或拍照并上传PHP实现

理解&#xff1a;微信上传接口是拍照&#xff0c;或者选择本地照片&#xff0c;上传到微信的服务器&#xff0c;获取到一个id&#xff0c;通过token与这个id获取到图片&#xff0c;保存到服务器即可。 效果 通过微信js接口&#xff0c;调用底层程序。 需要引入js文件&#xff0…