本系列博客旨在帮助大家理解java垃圾收集器及其工作原理,这是系列的第二篇。


java垃圾回收事实上是由一个能够进行自己主动内存管理的进程完毕的,这使得程序猿在写代码的时候不必过多考虑内存释放与回收的问题。



垃圾收集器怎样初始化:
作为一个自己主动化的进程,程序猿并不须要显式地在代码中初始化垃圾收集进程。所谓的System.gc()和Runtime.gc()都属于请求JVM初始化垃圾收集进程的钩子函数。虽然这样的请求机制为程序猿提供了一个初始化该进程的机会,可是实际上控制权仍掌握在JVM手中。也就是说JVM可以选择忽略程序猿的请求。因而不要指望虚拟机可以足够听话。其实,它总是基于堆内存Eden区域的内存分配情况来作出推断。而详细的推断方式虚拟机规范上并没有强制要求,这个因不同虚拟机实现而异。

垃圾收集进程:

垃圾收集就是一个回收无用空间使之将来能够又一次分配给其它对象用的进程。

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY2hkamo=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="" style="font-size:13.63636302947998px">

Eden区域:当实例被创建,优先存储在新生代的Eden区域。


Survivor区域(S0和S1):作为Minor GC(新生代GC)生命周期的一个步骤。Eden区域中的存活对象将会被移到S0区域。而S0区域中的存活对象在被GC扫描之后将会被移到S1区域。

而死亡对象将会被GC标记。

被标记的对象可能会在标记后由此进程去回收也可能由一个单独的进程去回收(有四种类型的垃圾收集器,下篇我们将会学习)。

老年代:老年代是堆内存的还有一个逻辑组成部分。gc运行完MinorGC之后,某些在S1区域中依然存活的对象
将会晋升到老年代(译者注:并非全部对象都可以晋升,仅仅有熬过若干次MinorGC的对象才干晋升。这里有个对象年龄的概念,详细可參见专栏其它文章),而无用对象将会被标记。

MajorGC:MajorGC事实上就是老年代GC,在此期间,垃圾收集进程会扫描老年代中全部对象,标记死亡对象,被标记的对象随后将会被回收而其它对象依然存活。

内存碎片:当被标记的对象被清除后。堆内存会出现一些“空洞”,即内存碎片。

为了提高对象分配的速度,我们应该清除掉这些内存碎片。当然,这取决于详细的gc回收器实现。



实例的终结:
对象实例被回收之前,垃圾收集器可能会调用其finalize方法。因而对象能够在此方法中进行一些资源释放的操作(译者注:没有复写finalize方法的对象似乎并不须要运行其父类的finalize方法,參考《深入理解java虚拟机 JVM高级特性与最佳实践》3.2.4节),虽然finalize方法在该对象被回收前是一定会被运行的,可是确并没有一个明白的时间和明白的顺序,多个待回收的实例调用finalize方法的先后顺序不能够被设置,它们甚至会并行的运行。(译者注:这里说的运行finalize方法只指触发这种方法,但虚拟机不承诺等待其运行结束,由于假设finalize方法运行时间过长,将会影响其它对象的回收,甚至导致整个内存回收系统崩溃

1.假设在回收一个垃圾对象的过程中出现异常,默认将会被忽略,而且取消回收该对象实例。

2.虚拟机规范并没有对虚引用的垃圾回收过程进行强制规定。细节由虚拟机实现者决定。
3.垃圾回收过程是由一个守护线程运行的。


对象何时能回收:
1.一个线程訪问不到该对象实例;
2.该对象(或者是若干对象循环引用)不被不论什么其它对象所引用。
(译者注:上面定义不是非常直观,事实上这里有个根引用算法以及GC root的概念,详细參见专栏其它文章)

java中有不同的引用类型,垃圾回收因引用类型而异。

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY2hkamo=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

在java编译器编译优化期间,能够选择给一个对象赋null表示该对象不再可用,能够被回收。

class Animal {
public static void main(String[] args) {
Animal lion = new Animal();
System.out.println("Main is completed.");
}
protected void finalize() {
System.out.println("Rest in Peace!");
}
}
上面代码中。lion对象在被声明后没有被使用过,所以java编译器作为一个编译优化措施能够通过加入lion=null在声明lion之后,所以在main方法的输出之前。finalize方法就已经输出“rest in Peace!”了,当然了。我们并不能保证输出这种结果,由于这取决于虚拟机实现以及内存使用情况。
(译者注:假设没有运行垃圾回收,则上述代码并不会调用finalize方法)可是我们学到一点。那就是编译器能够选择提前释放一个对象实例假设其预见到该对象将来不会被使用。

描写叙述GC范围的演示样例代码:

Class GCScope {
GCScope t;
static int i = 1;
public static void main(String args[]) {
GCScope t1 = new GCScope();
GCScope t2 = new GCScope();
GCScope t3 = new GCScope();
// No Object Is Eligible for GC
t1.t = t2; // No Object Is Eligible for GC
t2.t = t3; // No Object Is Eligible for GC
t3.t = t1; // No Object Is Eligible for GC
t1 = null;
// No Object Is Eligible for GC (t3.t still has a reference to t1)
t2 = null;
// No Object Is Eligible for GC (t3.t.t still has a reference to t2)
t3 = null;
// All the 3 Object Is Eligible for GC (None of them have a reference.
// only the variable t of the objects are referring each other in a
// rounded fashion forming the Island of objects with out any external
// reference)
}
protected void finalize() {
System.out.println("Garbage collected from object" + i);
i++;
}
GC OutOfMemoryError演示样例:
java世界也会有内存溢出问题。

import java.util.LinkedList;
import java.util.List;
public class GC {
public static void main(String[] main) {
List l = new LinkedList();
// Enter infinite loop which will add a String to the list: l on each
// iteration.
do {
l.add(new String("Hello, World"));
} while (true);
}
}

输出:

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.LinkedList.linkLast(LinkedList.java:142)
at java.util.LinkedList.add(LinkedList.java:338)
at com.javapapers.java.GCScope.main(GCScope.java:12)

下篇我们将介绍不同的垃圾收集器类型。

原文:http://javapapers.com/java/how-java-garbage-collection-works/

GC入门指南(二)------GC工作原理的更多相关文章

  1. 【SpringMVC架构】SpringMVC入门实例,解析工作原理(二)

    上篇博文,我们简单的介绍了什么是SpringMVC.这篇博文.我们搭建一个简单SpringMVC的环境,使用非注解形式实现一个HelloWorld实例,从简单入手,逐步深入. 环境准备 我们须要有主要 ...

  2. Struts2(二):工作原理

    struts可查看源码:https://github.com/apache/struts 在学习struts2之前,我先看了一些比较早版本对struts2的工作原理相关的介绍,顺便抄写过来,用来帮助自 ...

  3. require.js入门指南(二)

    *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !important; } /* ...

  4. kotlin 语言入门指南(二)--代码风格

    语言风格 这里整理了 kotlin 惯用的代码风格,如果你有喜爱的代码风格,可以在 github 上给 kotlin 提 pull request . 创建DTOs(POJSs/POCOs) 文件: ...

  5. 《转载》编程入门指南 v1.4

    编程入门指南 v1.4 Badger · 8 个月前 作者:@萧井陌, @Badger 自由转载-非商用-非衍生-保持署名 | Creative Commons BY-NC-ND 3.0 CoCode ...

  6. zabbix监控的基础概念、工作原理及架构

    一.什么是zabbix及优缺点(对比cacti和nagios) Zabbix能监视各种网络参数,保证服务器系统的安全运营:并提供灵活的通知机制以让系统管理员快速定位/解决存在的各种问题.是一个基于WE ...

  7. MapReduce 1工作原理图文详解

    MapReduce工作原理图文详解 一 MapReduce程序执行流程 程序执行流程图如下: 流程分析:1.在客户端启动一个作业.2.向JobTracker请求一个Job ID.3.将运行作业所需要的 ...

  8. Java中GC的工作原理

    转文: 一个优秀的Java程序员必须了解GC的工作原理.如何优化GC的性能.如何与GC进行有限的交互,有一些应用程序对性能要求较高,例如嵌入式系统.实时系统等,只有全面提升内存的管理效率,才能提高整个 ...

  9. JVM 的 工作原理,层次结构 以及 GC工作原理

    JVM Java 虚拟机 Java 虚拟机(Java virtual machine,JVM)是运行 Java 程序必不可少的机制.JVM实现了Java语言最重要的特征:即平台无关性.原理:编译后的 ...

随机推荐

  1. c# automapper 使用

    一.最简单的用法 有两个类User和UserDto 1 public class User 2 { 3 public int Id { get; set; } 4 public string Name ...

  2. hdu 4525(数学)

    威威猫系列故事——吃鸡腿 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Tota ...

  3. 搜狗拼音输入法LINUX版安装

    搜狗拼音输入法LINUX版官方下载: http://pinyin.sogou.com/linux/?r=pinyin 一.添加fcitx的nightlyPPA 在终端中输入: sudo add-apt ...

  4. Codeforces 最大流 费用流

    这套题目做完后,一定要反复的看! 代码经常出现的几个问题: 本机测试超时: 1.init函数忘记写. 2.addedge函数写成add函数. 3.边连错了. 代码TLE: 1.前向星边数组开小. 2. ...

  5. UVA 11059 Maximum Product【三层暴力枚举起终点】

    [题意]:乘积最大的子序列.n∈[1,10],s∈[-10,10] [代码]: #include<bits/stdc++.h> using namespace std; int a[105 ...

  6. IT人为了自己父母和家庭,更得注意自己的身体和心理健康

    我前一阵在一家互联网公司,工作节奏是995,忙的时候,要晚上10点才能离开公司,有时候周六还得加班.自己感觉身体状况有所下降,且听说其它一个组,在体检后多少都查出问题来,细思极恐. 有时候确实忙,那么 ...

  7. Linux(一) 软件安装

    前言:在Linux中安装软件时,我们经常要考虑到这样几个个问题: (1).怎样安装软件;       (2).软件安装在什么地方;       (3).如何卸载删除不要的软件...... 下面,我们就 ...

  8. MFC中 日期字符串的转换

    一.将字符串2011-08-1800:00:00转换为字符串2011-8-18,通过以下的函数 CString DataDeleteZero(CString DATA) { CStringstrmon ...

  9. ylb:sql语句重命名表名和列名

    ylbtech-SQL Server:SQL Server-sql语句重命名表名和列名 sql语句重命名表名和列名 ylb:sql语句重命名表名和列名 返回顶部 一.更改数据库名    sp_rena ...

  10. TortoiseGit在github上创建工程

    一.前期准备 TortoiseGit官网下载地址:http://code.google.com/p/tortoisegit/ git下载地址:https://git-scm.com/download/ ...