浅析Java内存区及其垃圾回收机制,java垃圾回收
浅析Java内存区及其垃圾回收机制,java垃圾回收
浅析Java内存区及其垃圾回收机制
- Java三大内存区
- Java堆与栈的形象描述
- 两种垃圾判别机制
- 两种垃圾回收技术
- JIT编译器技术简介
Java三大内存区
Java堆与栈的形象描述
堆
Java的堆比较特殊,《Java编程思想》(第4版)里把Java的堆(Java的堆是堆,Java的堆栈是栈)比作一个传送带,每分配一个新对象,它就往前移动一格。
但是其实这样的描述不够准确,因为这样的话会造成大量的空间浪费。我们可以设想,如果JVM真的像传送带一样实现堆,那么即使一个对象不在被使用,其存储空间也不会被释放。我们可以这样理解Java的堆:
C++的堆无法抽象成栈主要是因为其没有独立于用户程序的垃圾回收机制,每一块分配出去的存储实例对象的内存都要由其自身管理(包括销毁)。这也就是说难以实现对C++堆的整体内存再分配,所以如果把C++的结构抽象为栈这一数据结构的话,那么很难保证C++的堆不会满。而Java则不同了,其具有一个自动的,面向于JVM的垃圾回收机制(相当于MySQL 里的OPTIMIZE TABLE对表的作用);通过GC,那么我们可以利用虚拟机自动实现栈中空间的重新整理,并对Java栈中这些实例对象的引用变量的值进行自动更新(这也是Java引用与c的指针的区别之一)。
栈
下面说一下两种垃圾判别机制
引用计数
特点 | 描述 |
---|---|
发生时间 | 程序生命周期。 |
方式 | 每个对象都有一个引用计数器,当引用离开作用域或被置为null时减一,当对象被连接到一个新引用变量上时,计数器加1。当对象引用计数器为0时,释放对象。 |
优点 | 思想简单。 |
缺点 | 当出现循环引用的情况时,无法及时回收相关对象;且JVM判断循环引用的开销较大。 |
可以使用冒号来定义对齐方式:
追溯堆栈或静态存储区活引用法
这种方法,就是从堆栈和静态存储区开始,遍历所有引用,对于发现的每个对象,再遍历此对象所包含的所有引用,反复进行。类似于图的遍历,在这个图里的所有节点(对象)都是活的,剩余的对象就可以被判别为回收了。而且,因为“引用计数”法中的交互引用对象几乎不会在堆栈和静态存储区中(而是随着对象存储在堆中)出现,所以几乎完全避免了这个现象。
两种垃圾回收技术
总括 《Java编程思想》(第四版中文版)关于JVM垃圾回收技术的概括:
自适应的、分代的、停止-复制、标记-清扫的。
我们先来介绍下停止-复制技术的步骤:
1. 暂停程序运行(这点看出其不属于后台回收模式);
2. 将堆中存活的对象从当前堆(或者是当前堆中的块),复制到另一个可用堆(或者是当前堆中可用的块)中;
3. 原来的堆(块)中就只剩下垃圾,交给GC处理。
注意:
于是,引出了标记-清扫方式
1. JVM从静态存储区和栈开始遍历所有引用,标记其中所有获得引用;
2. 之后,标记工作结束时,JVM回收没有被标记的对象。但是,不发生对象复制,所以会节省空间和时间,但并没有起到使对象紧凑排列的作用。
自适应
JVM会监视垃圾回收效率,选择并切换这两种方式进行垃圾回收。
分代
Java虚拟机的分代比较复杂,可以参考这篇文章。
JIT
可以参考这篇文章,哈哈!偷个懒,这两个东西要说的太多了!。
相关文章
- 暂无相关文章
用户点评