Java编程开发之浅析Java引用机制

对于一个Java的对象而言,存储主要分为两种,一种是内存堆(Heap),内存堆是无序的,主要用来存放创建的Java对象;一种是内存栈(Stack),主要用来存放Java引用,然后在管理过程使用Java引用指向Java对象。

关于Reference引用的“那些事儿"

随着黄金梅丽号在大海之上的飘荡,一切看着是那么的风平浪静,但是每个人似乎都在忙着自己手里的那些事情....突然韦柏向萨博提出了一个问题:都知道JVM调优是当下从事Java开发必须要去具备甚至要去提升自己的一个重要环节,那你知道堆与栈,各自存放机制是什么?也就针对于这个问题,就像当初去探索世界尽头的梦想一样,萨博这样回答韦柏:对于一个Java的对象而言,存储主要分为两种,一种是内存堆(Heap),内存堆是无序的,主要用来存放创建的Java对象;一种是内存栈(Stack),主要用来存放Java引用,然后在管理过程使用Java引用指向Java对象。 听完萨博的回答,韦柏靠在甲板上,点燃了一支猩红的香烟,抽了一口,然后对萨博说道:那你能详细的讲解一下这个引用机制么?萨博思考了一下,于是有了以下的故事.......

GC[Garbage Collectors]的基本原理

在引入Reference引用的概念之前,我们需要清楚的知道内存栈(Stack)和内存堆(Heap)在JVM虚拟机的结构分布以及基本情况,如上图所示。综上所述,我们可以了解到Java的内存管理实际上就是对象的管理,包括对象实例的分配和释放。其中GC的存在就是负责在对象“不可达”的时候将对象回收处理。当系统在创建对象实例的时候,即当使用new关键字创建一个对象的时候,GC就开始监控对象的地址、大小以及使用状态。一般情况下,Java的GC机制都有特定的回收算法,GC通常会使用有向图的方式来记录队中的所有对象,通过此种方式确定甚至标记哪些对象是“可达的”,而哪些是“不可达的”。当GC判断一些对象不可达的时候,GC就有责任回收相关内存空间,是否能被垃圾回收机制回收,具体操作是取决于机器和平台,但判断依据主要是看对象是否有引用指向该对象。

Reference引用基本概述

Abstract base class for reference objects. This class defines the operations common to all reference objects. Because reference objects are implemented in close cooperation with the garbage collector, this class may not be subclassed directly.

不难发现,Reference机制对JVM的垃圾收集活动敏感,Reference的继承关系或者实现是由JDK定制,引用实例是由JVM创建,一般不推荐自行继承Reference实现自定义的引用类型,但是可以继承已经存在的引用类型。
JDK提供了强引用(Strong Reference)、软引用(Soft Reference)、弱引用(Weak Reference)和虚引用(Phantom Reference),引用队列(ReferenceQueue)以及析构引用(Final Reference)等引用类型。

[⚠️注意事项]:

  1. 强引用可能对垃圾收集活动是不敏感的
  2. 自行继承Reference实现自定义的引用类型,其反复造轮子的意义不大。
  3. 析构引用(Final Reference),它是一种特化的虚引用
  4. 不同JDK版本,需要注意实际源码的对比分析。
    5.Reference是所有引用对象的基类

Reference引用类型分析

强引用(Strong Reference):在Java中最常见的就是强引用,也是最普遍存在的引用类型。处于可达状态,是不可能被垃圾回收机制回收的,即使该对象以后永远都不会被用到JVM也不会回收。

软引用(Soft Reference):对于只有软引用的对象来说,当系统内存足够时它不会被回收,当系统内存空间不足时它会被回收。软引用通常用在对内存敏感的程序中。

弱引用(Weak Reference):比软引用的生存期更短,对于只有弱引用的对象来说,只要垃圾回收机制一运行,不管JVM的内存空间是否足够,总会回收该对象占用的内存。
虚引用(Phantom Reference):不能单独使用,必须和引用队列联合使用。虚引用的主要作用是跟踪对象被垃圾回收的状态。
引用队列(ReferenceQueue)
析构引用(Final Reference)

[⚠️注意事项]:

  1. 强引用可能对垃圾收集活动是不敏感的,没有对应的类型表示,也就是说强引用是普遍存在的,如Object object = new Object();。
  2. 软引用、弱引用和虚引用都是java.lang.ref.Reference的直接子类。
  3. 直到JDK11为止,只存在四种引用,这些引用是由JVM创建,因此直接继承java.lang.ref.Reference创建自定义的引用类型是无效的,但是可以直接继承已经存在的引用类型,如java.lang.ref.Cleaner就是继承自java.lang.ref.PhantomReference。
  4. 特殊的java.lang.ref.Reference的子类java.lang.ref.FinalReference和Object#finalize()有关,java.lang.ref.Finalizer是java.lang.ref.FinalReference子类。
    版权声明:本文为博主原创文章,遵循相关版权协议,如若转载或者分享请附上原文出处链接和链接来源。
(0)

相关推荐

  • JVM 堆中对象分配、布局和访问

    本文摘自深入理解 Java 虚拟机第三版 对象的创建 Java 是一门面向对象的语言,Java 程序运行过程中无时无刻都有对象被创建出来.从语言层面看,创建对象只是一个 new 关键字而已,而在虚拟机 ...

  • 深入解析JVM原理,JVM到底是什么

    运行时数据区结构 堆.栈.方法去的交互关系 1.介绍: <Java虚拟机规范>中明确说明:"尽管所有的方法区在逻辑上是属于堆的一部分,但一些简单的实现可能不会选择去进行垃圾收集或 ...

  • Java开发过程中会出现哪些OOM?

    什么是OOM?OOM时Java开发中不可避免的一个常见问题,尤其在面试时,面试官会经常问到"谈谈你对OOM的认识".本文整理一些Java开发过程中常见的OOM,希望看完本文对大家有 ...

  • Java中的Reference类使用

    Java 2 平台引入了 java.lang.ref 包,这个包下面包含了几个Reference相关的类,Reference相关类将Java中的引用也映射成一个对象,这些类还提供了与垃圾收集器(gar ...

  • Java编程技术之浅析Java容器技术

    Java容器 集合是一种存储数据的容器,是Java开发中使用最频繁的对象类型之一. 或许提起Collection,都会第一时间意识到List和Set以及Map等相关关键词.因为这几乎是我们日常开发里接 ...

  • Java编程技术之浅析JVM内存

    JVM JVM->Java Virtual Machine:Java虚拟机,是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的. 基本认知: ...

  • ITeye Java编程 Spring框架 Ajax技术 agile敏捷软件开发 ruby on r...

    ITeye Java编程 Spring框架 Ajax技术 agile敏捷软件开发 ruby on r...

  • Android插件化开发基础之Java反射机制研究

    一.获得Class对象 Class<?> c = Class.forName("classname"); 抛出ClassNotFoundException 二.获得实现 ...

  • Android插件化开发基础之Java动态代理(proxy)机制的简单例子

    一.代码 package com.sangfor.tree; import java.lang.reflect.InvocationHandler; import java.lang.reflect. ...

  • 收藏!Java编程技巧之单元测试用例编写流程

    温馨提示:本文较长,同学们可收藏后再看 :) 前言 清代杰出思想家章学诚有一句名言:"学必求其心得,业必贵其专精." 意思是:学习上一定要追求心得体会,事业上一定要贵以专注精深.做 ...

  • JAVA编程环境与基本数据类型

    随笔目录 # <JAVA编程环境与基本数据类型> 随笔目录 - Java小实例 java的编程环境 java数据类型 Java小实例 java的编程环境 Linux*Lubuntu下安装与 ...

  • Java编程技巧之样板代码

    前言 北宋科学家沈括在<梦溪笔谈>第十八卷<技艺>中这样描述"活字印刷术": 庆历中,有布衣毕昇,又为活版.其法用胶泥刻字,薄如钱唇,每字为一印,火烧令坚- ...

  • 0基础学Java(四)开发第一个Java程序HelloWorld

    开发第一个Java程序:HelloWorld 1.程序写完之后,一定要ctrl + s 进行保存 第一个HelloWorld程序照抄就行了,不要问代码为什么这么写. 另外,大家需要注意的是:java源 ...