对于一个Java的对象而言,存储主要分为两种,一种是内存堆(Heap),内存堆是无序的,主要用来存放建立的Java对象;一种是内存栈(Stack),主要用来存放Java引用,而后在管理过程使用Java引用指向Java对象。java
随着黄金梅丽号在大海之上的飘荡,一切看着是那么的风平浪静,可是每一个人彷佛都在忙着本身手里的那些事情....忽然韦柏向萨博提出了一个问题:都知道JVM调优是当下从事Java开发必需要去具有甚至要去提高本身的一个重要环节,那你知道堆与栈,各自存放机制是什么?也就针对于这个问题,就像当初去探索世界尽头的梦想同样,萨博这样回答韦柏:对于一个Java的对象而言,存储主要分为两种,一种是内存堆(Heap),内存堆是无序的,主要用来存放建立的Java对象;一种是内存栈(Stack),主要用来存放Java引用,而后在管理过程使用Java引用指向Java对象。 听完萨博的回答,韦柏靠在甲板上,点燃了一支猩红的香烟,抽了一口,而后对萨博说道:那你能详细的讲解一下这个引用机制么?萨博思考了一下,因而有了如下的故事.......算法
在引入Reference引用的概念以前,咱们须要清楚的知道内存栈(Stack)和内存堆(Heap)在JVM虚拟机的结构分布以及基本状况,如上图所示。综上所述,咱们能够了解到Java的内存管理实际上就是对象的管理,包括对象实例的分配和释放。其中GC的存在就是负责在对象“不可达”的时候将对象回收处理。当系统在建立对象实例的时候,即当使用new关键字建立一个对象的时候,GC就开始监控对象的地址、大小以及使用状态。通常状况下,Java的GC机制都有特定的回收算法,GC一般会使用有向图的方式来记录队中的全部对象,经过此种方式肯定甚至标记哪些对象是“可达的”,而哪些是“不可达的”。当GC判断一些对象不可达的时候,GC就有责任回收相关内存空间,是否能被垃圾回收机制回收,具体操做是取决于机器和平台,但判断依据主要是看对象是否有引用指向该对象。oop
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.this
不难发现,Reference机制对JVM的垃圾收集活动敏感,Reference的继承关系或者实现是由JDK定制,引用实例是由JVM建立,通常不推荐自行继承Reference实现自定义的引用类型,可是能够继承已经存在的引用类型。
JDK提供了强引用(Strong Reference)、软引用(Soft Reference)、弱引用(Weak Reference)和虚引用(Phantom Reference),引用队列(ReferenceQueue)以及析构引用(Final Reference)等引用类型。对象
[⚠️注意事项]:blog
- 强引用可能对垃圾收集活动是不敏感的
- 自行继承Reference实现自定义的引用类型,其反复造轮子的意义不大。
- 析构引用(Final Reference),它是一种特化的虚引用
- 不一样JDK版本,须要注意实际源码的对比分析。
5.Reference是全部引用对象的基类
强引用(Strong Reference):在Java中最多见的就是强引用,也是最广泛存在的引用类型。处于可达状态,是不可能被垃圾回收机制回收的,即便该对象之后永远都不会被用到JVM也不会回收。继承
软引用(Soft Reference):对于只有软引用的对象来讲,当系统内存足够时它不会被回收,当系统内存空间不足时它会被回收。软引用一般用在对内存敏感的程序中。队列
弱引用(Weak Reference):比软引用的生存期更短,对于只有弱引用的对象来讲,只要垃圾回收机制一运行,无论JVM的内存空间是否足够,总会回收该对象占用的内存。
虚引用(Phantom Reference):不能单独使用,必须和引用队列联合使用。虚引用的主要做用是跟踪对象被垃圾回收的状态。
引用队列(ReferenceQueue):
析构引用(Final Reference):内存
[⚠️注意事项]:开发
- 强引用可能对垃圾收集活动是不敏感的,没有对应的类型表示,也就是说强引用是广泛存在的,如Object object = new Object();。
- 软引用、弱引用和虚引用都是java.lang.ref.Reference的直接子类。
- 直到JDK11为止,只存在四种引用,这些引用是由JVM建立,所以直接继承java.lang.ref.Reference建立自定义的引用类型是无效的,可是能够直接继承已经存在的引用类型,如java.lang.ref.Cleaner就是继承自java.lang.ref.PhantomReference。