Java语言的垃圾回收机制
java语言从诞生开始,一个吸引人眼球的功能就是垃圾回收,想一想C++中时不时的内存泄漏,当时感觉写java代码直是一种享受呀。 和.NET的引用计数不同,java的垃圾回收机制采取的是有向图的方式来实现,具体的说,java程序中的每个线程对象就可以看作是一个有向图的起点,有向边从栈中的引用者指向堆中的引用对象。在这个有向图中,如果一个对象和根节点之间是可达的,那么这个对象就是有效的,反之,这个对象就是可以被回收的。采取这样一种机制的优点是可以有效的避免循环引用。 java语言中的对象引用分为以下几种:强引用、软引用、弱引用和虚引用。 强引用就是我们经常用到的引用,这种引用在对象被标识为无效后,不会被立刻回收,除非写o = null;这种语句。 软引用,如果一个被软引用的对象被标识为无效后,在内存控件足够的情况下,不会被回收,在内存紧张的情况下,会被回收的。 弱引用,如果一个被弱引用的对象被标识为无效,那么对象会被立刻回收。 虚引用,这是一种不太真实可用的引用类型,它的主要用途是结合引用关联队列,实现对对象引用关系的跟踪。 四种引用的Sample如下:
1 import java.lang.ref.SoftReference;
2 import java.lang.ref.WeakReference;
3 import java.lang.ref.PhantomReference;
4 import java.lang.ref.ReferenceQueue;
5 import java.util.HashSet;
6 import java.util.Set;
7
8 class MyObject {
9 private String id;
10
11 public MyObject(String id) {
12 this.id = id;
13 }
14
15 public String toString() {
16 return id;
17 }
18
19 public void finalize() {
20 System.out.println("Object Collect: " + id);
21 }
22}
23
24 public class ReferenceTest {
25
26 public static void main(String[] args) {
27 // TODO Auto-generated method stub
28
29 int length = 10;
30
31 Set<MyObject> a = new HashSet<MyObject>();
32 for (int i = 0; i < length; i++) {
33 MyObject ref = new MyObject("Hard_" + i);
34 System.out.println("Create Strong Refence: " + ref);
35 a.add(ref);
36 }
37 System.out.println();
38 System.gc();
39 System.out.println();
40
41 Set<SoftReference<MyObject>> sa = new HashSet<SoftReference<MyObject>>();
42 for (int i = 0; i < length; i++) {
43 SoftReference<MyObject> ref = new SoftReference<MyObject>(new MyObject("Soft_" + i));
44 System.out.println("Create Soft Refence: " + ref);
45 sa.add(ref);
46 }
47 System.out.println();
48 System.gc();
49 System.out.println();
50
51 Set<WeakReference<MyObject>> wa = new HashSet<WeakReference<MyObject>>();
52 for (int i = 0; i < length; i++) {
53 WeakReference<MyObject> ref = new WeakReference<MyObject>(new MyObject("Weak_" + i));
54 System.out.println("Create Weak Refence: " + ref);
55 wa.add(ref);
56 }
57 System.out.println();
58 System.gc();
59 System.out.println();
60
61 ReferenceQueue rq = new ReferenceQueue<MyObject>();
62 Set<PhantomReference<MyObject>> pa = new HashSet<PhantomReference<MyObject>>();
63 for (int i = 0; i < length; i++) {
64 //MyObject ref = new MyObject("Hard_" + i);
65 PhantomReference<MyObject> ref = new PhantomReference<MyObject>(new MyObject("Phantom_" + i), rq);
66 System.out.println("Create Phantom Refence: " + ref);
67 pa.add(ref);
68 }
69 System.out.println();
70 System.gc();
71 System.out.println();
72 }
执行结果如下:
Create Strong Refence: Hard_0 Create Strong Refence: Hard_1 Create Strong Refence: Hard_2 Create Strong Refence: Hard_3 Create Strong Refence: Hard_4 Create Strong Refence: Hard_5 Create Strong Refence: Hard_6 Create Strong Refence: Hard_7 Create Strong Refence: Hard_8 Create Strong Refence: Hard_9
Create Soft Refence: java.lang.ref.SoftReference@1270b73 Create Soft Refence: java.lang.ref.SoftReference@60aeb0 Create Soft Refence: java.lang.ref.SoftReference@16caf43 Create Soft Refence: java.lang.ref.SoftReference@66848c Create Soft Refence: java.lang.ref.SoftReference@8813f2 Create Soft Refence: java.lang.ref.SoftReference@1d58aae Create Soft Refence: java.lang.ref.SoftReference@83cc67 Create Soft Refence: java.lang.ref.SoftReference@e09713 Create Soft Refence: java.lang.ref.SoftReference@de6f34 Create Soft Refence: java.lang.ref.SoftReference@156ee8e
Create Weak Refence: java.lang.ref.WeakReference@e0e1c6 Create Weak Refence: java.lang.ref.WeakReference@6ca1c Create Weak Refence: java.lang.ref.WeakReference@1bf216a Create Weak Refence: java.lang.ref.WeakReference@12ac982 Create Weak Refence: java.lang.ref.WeakReference@1389e4 Create Weak Refence: java.lang.ref.WeakReference@c20e24 Create Weak Refence: java.lang.ref.WeakReference@2e7263 Create Weak Refence: java.lang.ref.WeakReference@157f0dc Create Weak Refence: java.lang.ref.WeakReference@863399 Create Weak Refence: java.lang.ref.WeakReference@a59698
Create Phantom Refence: java.lang.ref.PhantomReference@5740bb Create Phantom Refence: java.lang.ref.PhantomReference@5ac072 Create Phantom Refence: java.lang.ref.PhantomReference@109a4c Create Phantom Refence: java.lang.ref.PhantomReference@201f9 Create Phantom Refence: java.lang.ref.PhantomReference@1cf8583 Create Phantom Refence: java.lang.ref.PhantomReference@14693c7 Create Phantom Refence: java.lang.ref.PhantomReference@901887 Create Phantom Refence: java.lang.ref.PhantomReference@3a6727 Create Phantom Refence: java.lang.ref.PhantomReference@4a65e0 Create Phantom Refence: java.lang.ref.PhantomReference@665753
Object Collect: Phantom_6 Object Collect: Phantom_9 Object Collect: Phantom_8 Object Collect: Phantom_7 Object Collect: Phantom_5 Object Collect: Phantom_4 Object Collect: Phantom_3 Object Collect: Phantom_2 Object Collect: Phantom_1 Object Collect: Phantom_0 Object Collect: Weak_9 Object Collect: Weak_8 Object Collect: Weak_7 Object Collect: Weak_6 Object Collect: Weak_5 Object Collect: Weak_4 Object Collect: Weak_3 Object Collect: Weak_2 Object Collect: Weak_1 Object Collect: Weak_0
虽然java语言采取了比.NET更好的垃圾回收机制,但是它也存在内存泄漏的时候,考虑以下情况:
1 Vector v = new Vector(10);
2 for (int i = 0; i < 10; i++) {
3 object o = new object();
4 v.add(o);
5 o = null;
6 }
对于每次建立的对象o,虽然最后通过o = null;语句来表明它是无效的,但是我们可以通过Vector来引用到它,这样,如果在Vector使用完毕后没有被显示的释放,即没有v = null;的话,这里就产生了内存泄漏。
Java语言的垃圾回收机制的更多相关文章
- java中存在垃圾回收机制,但是还会有内存泄漏的问题,原因是
答案是肯定的,但不能拿这一句回答面试官的问题.分析:JAVA是支持垃圾回收机制的,在这样的一个背景下,内存泄露又被称为“无意识的对象保持”.如果一个对象引用被无意识地保留下来,那么垃圾回收器不仅不会处 ...
- java基础之 垃圾回收机制
1. 垃圾回收的意义 在C++中,对象所占的内存在程序结束运行之前一直被占用,在明确释放之前不能分配给其它对象:而在Java中,当没有对象引用指向原先分配给某个对象的内存时,该内存便成为垃圾.JVM的 ...
- Java中的垃圾回收机制
1. 垃圾回收的意义 在C++中,对象所占的内存在程序结束运行之前一直被占用,在明确释放之前不能分配给其它对象:而在Java中,当没有对象引用指向原先分配给某个对象的内存时,该内存便成为垃圾.JVM的 ...
- Java中的垃圾回收机制&内存管理&内存泄漏
1. Java在创建对象时,会自动分配内存,并当该对象引用不存在的时候,释放这块内存. 为什么呢? 因为Java中使用被称为垃圾收集器的技术来监视Java程序的运行,当对象不再使用时,就自动释放对象所 ...
- java有自动垃圾回收机制
当垃圾收集器判断已经没有任何引用指向对象的时候,会调用对象的finalize方法来释放对象占据的内存空间~ java中垃圾回收以前听老师讲好像是内存满了他才去做一次整体垃圾回收,在回收垃圾的同时会调用 ...
- JAVA中的垃圾回收机制以及其在android开发中的作用
http://blog.csdn.net/xieqibao/article/details/6707519 这篇文章概述了JAVA中运行时数据的结构,以及垃圾回收机制的作用.在后半部分,描述了如何检测 ...
- Java学习之垃圾回收机制
垃圾回收机制,依赖JRE和JVM,涉及操作系统中内存的分配与回收.依据所学,我猜想这种机制需要的数据结构是堆内存分配表(链),管理已分配和未分配的堆内存,对于已分配堆内存,需要知道由栈内存中的哪些变量 ...
- Java基础教程——垃圾回收机制
垃圾回收机制 Garbage Collection,GC 垃圾回收是Java的重要功能之一. |--堆内存:垃圾回收机制只回收堆内存中对象,不回收数据库连接.IO等物理资源. |--失去使用价值,即为 ...
- 【java虚拟机】垃圾回收机制详解
作者:平凡希 原文地址:https://www.cnblogs.com/xiaoxi/p/6486852.html 一.为什么需要垃圾回收 如果不进行垃圾回收,内存迟早都会被消耗空,因为我们在不断的分 ...
随机推荐
- 结合Ajax做地区内容切换!(城市切换)
实现原理:点击,进行异步保存Cookie , 根据保存的Cookie来切换城市内容: 简单HTML示例: <!doctype html> <html> <head> ...
- rest_framework之序列化详解 06
拿到所有的角色数据 1.urls.py 2.models.py 假设只有3个角色 3.views.py from api import models import json json只能序列化pyt ...
- Linux系统下 Supervisor 安装搭建
在 web 应用部署到线上后,需要保证应用一直处于运行状态,在遇到程序异常.报错等情况,导致 web 应用终止时,需要保证程序可以立刻重启,继续提供服务. 所以,就需要一个工具,时刻监控 web 应用 ...
- C#6.0语法特性
1.自动属性初始化的改进(有用) 原来的用法(声明时无法同时初始化),例如: class MyClass { public int Age { get; set; } public string Na ...
- Oracle数据库误删文件导致rman备份报错RMAN-06169解决办法
Oracle数据库误删文件导致rman备份报错RMAN-06169解决办法 可能是误删文件导致在使用rman备份时候出现以下提示 RMAN-06169: could not read file hea ...
- hdu6386 Age of Moyu【最短路】
Age of Moyu Time Limit: 5000/2500 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others) To ...
- Object类中常见的方法,为什么wait notify会放在Object里边
toString():输出一个对象的地址字符串(哈希code码):可以通过重写toString方法,获取对象的属性! equals():比较的是对象的引用是否指向同一块内存地址, 重写equals() ...
- Expedition---poj2431(优先队列-堆的实现)
题目链接:http://poj.org/problem?id=2431 题意:一辆卡车需要行驶 L 距离,车上油的含量为 P,在行驶的过程中有 n 个加油站 每个加油站到终点的距离是ai,每个加油站最 ...
- Popular Cows---poj2186(缩点,强联通)
题目链接:http://poj.org/problem?id=2186 求有多少个点满足其他n-1个点都能到达这个点,是单向图: 所以我们可以把图进行缩点,之后求出度为0的那个点内包含的点的个数就是求 ...
- 【Jenkins学习 】解决jenkins运行磁盘满的问题
一.背景 今天有同事编译Jenkins的相关Jobs的时候,出现了编译成功,但是输出产物失败的情况,如下图所示: Caused by:java.io.IOException: No space lef ...