Java内存区域和判断对象“死”“活”算法
转载自: http://www.cnblogs.com/aigongsi/archive/2012/04/06/2434771.html
java与C,c++有很大的不同就是java语言开发者不需要关注内存信息,不会显式的直接操作内存,而是通过jvm虚拟机来实现。
java虚拟机运行的时候内存分配图如下图:

jvm虚拟机栈:一个是线程独有的,每次启动一个线程,就创建一个jvm虚拟机栈,线程退出的时候就销毁。这里面主要保存线程本地变量名和局部变量值。
本地方法栈: 调用本地jni方法的时候而创建的。这里分配的jvm之外的内存空间。方法调用结束之后销毁。
pc寄存器 : 这个保存线程当前执行的字节码指令
堆:主要保存创建的对象。
方法区:保存class相关的信息。主要是class的一个内存结构信息
常量池:方法区的一部分,主要保存class内存结构中常量值 例如String值,public static final 类型的值
我们这里说的垃圾回收,主要是java虚拟机对堆内存区域的回收。
1 首先的问题是:jvm如何知道那些对象需要回收 ?
目前有两种算法
- 引用计数法
每个对象上都有一个引用计数,对象每被引用一次,引用计数器就+1,对象引用被释放,引用计数器-1,直到对象的引用计数为0,对象就标识可以回收
这个可以用数据算法中的图形表示,对象A-对象B-对象C 都有引用,所以不会被回收,对象B由于没有被引用,没有路径可以达到对象B,对象B的引用计数就就是0,对象B就会被回收。
但是这个算法有明显的缺陷,对于循环引用的情况下,循环引用的对象就不会被回收。例如下图:对象A,对象B 循环引用,没有其他的对象引用A和B,则A和B 都不会被回收。
- root搜索算法
这种算法目前定义了几个root,也就是这几个对象是jvm虚拟机不会被回收的对象,所以这些对象引用的对象都是在使用中的对象,这些对象未使用的对象就是即将要被回收的对象。简单就是说:如果对象能够达到root,就不会被回收,如果对象不能够达到root,就会被回收。
如下图:对象D访问不到根对象,所以就会被回收
以下对象会被认为是root对象:
- 被启动类(bootstrap加载器)加载的类和创建的对象
- jvm运行时方法区类静态变量(static)引用的对象
- jvm运行时方法去常量池引用的对象
- jvm当前运行线程中的虚拟机栈变量表引用的对象
- 本地方法栈中(jni)引用的对象
由于这种算法即使存在互相引用的对象,但如果这两个对象无法访问到根对象,还是会被回收。如下图:对象C和对象D互相引用,但是由于无法访问根,所以会被回收。
jvm在确定是否回收的对象的时候采用的是root搜索算法来实现。
在root搜索算法的里面,我们说的引用这里都指定的是强引用关系。所谓强引用关系,就是通过用new 方式创建的对象,并且显示关联的对象
|
1
|
Object obj = new Object(); |
以上就是代表的是强引用关系,变量obj 强引用了 Object的一个对象。
java里面有四种应用关系,从强到弱分别为:
Strong Reference(强引用) –>Weak Reference (弱引用) -> Soft Reference(软引用) – > Phantom Reference(引用)
Strong Reference : 只有在引用对象root不可达的情况下才会标识为可回收,垃圾回收才可能进行回收
Weak Reference :即使在root算法中 其引用的对象root可达到,但是如果jvm堆内存 不够的时候,还是会被回收。
Soft Reference : 无论其引用的对象是否root可达,在响应内存需要时,由垃圾回收判断是否需要回收。
Phantom Reference :在回收器确定其指示对象可另外回收之后,被加入垃圾回收队列.
下面可以看一个测试
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
public class ReferenceTest { public static final Map<Integer, Reference> map = new HashMap<Integer, Reference>(); public static void main(String[] args) { for (int i = 0; i < 1000; i++) { map.put(i, new WeakReference(new ReferenceObject(i))); } int i = 0; for (Reference r : map.values()) { if (r.get() == null) { i++; } } System.out.println("被回收的对象数:" + i); } static class ReferenceObject { private int i; private byte[] b; public ReferenceObject(int i) { this.i = i; b = new byte[1024 *10]; } }} |
这里创建大约1000个 10K的 Weak Reference 对象,最后打印的结果是:被回收的对象数:767,这里ReferenceObject如果设置为1K的话,最后的打印结果是0
这个例子并不严谨,但是却说明了被Weak Reference的对象在一定的时候会被jvm回收,但是强引用就不会出现这种状态。
Java内存区域和判断对象“死”“活”算法的更多相关文章
- Java虚拟机2:Java内存区域及对象
几个计算机的概念 为以后写文章考虑,也为巩固自己的知识和一些基本概念,这里要理清楚几个计算机中的概念. 1.计算机存储单位 从小到大依次为位Bit.字节Byte.千字节KB.兆M.千兆GB.TB,相邻 ...
- Java内存区域与对象创建过程
一.java内存区域 Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域.这些区域都有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启动而存在,有的区域则 ...
- Java内存区域和对象的创建
文章绝大部分内存摘抄自<深入理解Java虚拟机>,结合了小部分个人理解如果有什么错误,还望指出,如果涉及到侵权,联系博主,立马删除,再次感谢<深入理解Java虚拟机>的作者-周 ...
- 《深入理解Java虚拟机》-----第2章 Java内存区域与内存溢出异常
2.1 概述 对于从事C.C++程序开发的开发人员来说,在内存管理领域,他们即是拥有最高权力的皇帝又是执行最基础工作的劳动人民——拥有每一个对象的“所有权”,又担负着每一个对象生命开始到终结的维护责任 ...
- Java 内存区域和GC机制分析
目录 Java垃圾回收概况 Java内存区域 Java对象的访问方式 Java内存分配机制 Java GC机制 垃圾收集器 Java垃圾回收概况 Java GC(Garbage Collection, ...
- Java 内存区域和GC机制
目录 Java垃圾回收概况 Java内存区域 Java对象的访问方式 Java内存分配机制 Java GC机制 垃圾收集器 Java垃圾回收概况 Java GC(Garbage Collection, ...
- Java系列笔记(3) - Java 内存区域和GC机制
目录 Java垃圾回收概况 Java内存区域 Java对象的访问方式 Java内存分配机制 Java GC机制 垃圾收集器 Java垃圾回收概况 Java GC(Garbage Collection, ...
- Java 内存区域和GC机制--备用
Java垃圾回收概况 Java GC(Garbage Collection,垃圾收集,垃圾回收)机制,是Java与C++/C的主要区别之一,作为Java开发者,一般不需要专门编写内存回收和垃圾清理代 ...
- JAVA内存区域和GC机制
目录 Java垃圾回收概况 Java内存区域 Java对象的访问方式 Java内存分配机制 Java GC机制 垃圾收集器 Java垃圾回收概况 Java GC(Garbage Collection, ...
随机推荐
- shell脚本小技巧
输入参数错误时,退格会出现^H,这个时候只要在脚本顶部加一条语句:stty erase ^h就可以了 #!/bin/sh stty erase ^h
- win10 python nltk安装
主要是参照http://www.tuicool.com/articles/VFf6Bza
- 坑爹的SQL ISNUMERIC
select ISNUMERIC('01,02') ISNUMERIC返回 1,后面用patindex代替了...折腾/ select patindex('%[^0-9]%','01,02')
- Android系统版本与API Level对照表
Platform Version API Level VERSION_CODE Notes Android 4.2 17 JELLY_BEAN_MR1 Android 4.1, 4.1.1 16 ...
- JavaEE基础(九)
1.面向对象(多态的概述及其代码体现) A:多态(polymorphic)概述 事物存在的多种形态 B:多态前提 a:要有继承关系. b:要有方法重写. c:要有父类引用指向子类对象. C:案例演示 ...
- JavaEE基础(六)
1.面向对象(面向对象思想概述) A:面向过程思想概述 第一步 第二步 B:面向对象思想概述 找对象(第一步,第二步) C:举例 买煎饼果子 洗衣服 D:面向对象思想特点 a:是一种更符合我们思想习惯 ...
- HDU 5950:Recursive sequence(矩阵快速幂)
http://acm.hdu.edu.cn/showproblem.php?pid=5950 题意:给出 a,b,n,递推出 f(n) = f(n-1) + f(n-2) * 2 + n ^ 4. f ...
- DomainHelper
public class DomainHelper { public static void SetDomainValue(string key, object password) { AppDoma ...
- 在Ecshop后台打印订单页面将商品按货号排序
ECSHOP后台管理里的“打印订单" 页面里的商品排序有点乱,现在想改成按序号来排序,修改方法如下 下面是在2.7.2基础上做的修改 打开 admin/order.php 文件 找到(大约 ...
- css常用命名规则
(一)常用的CSS命名规则 头:header 内容:content/container 尾:footer 导航:nav 侧栏:sidebar 栏目:column 页面外围控制整体布局宽度:wrappe ...



