本系列博客旨在帮助大家理解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. Android Bluetooth抓包

    1. 前提 这里介绍一种在Android上捕获蓝牙数据包的方法 首先你要有一部Android手机:然后你的Android系统版本要在4.4及以上 我没有做过Android开发,不清楚开发者们是如何抓蓝 ...

  2. Codeforces 903F Clear The Matrix(状态压缩DP)

    题目链接 Clear The Matrix 题意 给定一个$4 * n$的矩形,里面的元素为$'.'$或$'*'$.现在有$4$种正方形可以覆盖掉$'*'$,正方形的边长分别为$1,2,3,4$. 求 ...

  3. 对CSDN的理性吐槽

    CSDN博客网站首页挂了....从使用CSDN博客以来,大大小小的故障出过十几次.........再这样的话我都要对这个网站失去信心了

  4. 性能调优培训 windbg --woodytu

    http://www.cnblogs.com/woodytu/p/4675479.html http://www.cnblogs.com/fjicn/p/3405716.html http://www ...

  5. devicemapper: Error running deviceCreate (ActivateDevice) dm_task_run failed

    在一台新机子上面,docker处理完lvs数据卷之后,启动docker服务时,出现了启动失败,失败信息如下: [root@hxin221 ~]# systemctl status docker ● d ...

  6. 查看linux 系统 当前使用的网卡

    使用ifconfig命令查看到linux 系统有三个网卡 ,其实我只要其中一个启用就可以了,用什么命令查看或者切换网卡,或者停用掉其他两个网卡? watch cat /proc/net/dev 看下哪 ...

  7. 关于IIS的IUSER和IWAM帐户

    IUSER是Internet 来宾帐户匿名访问 Internet 信息服务的内置帐户 IWAM是启动 IIS 进程帐户用于启动进程外的应用程序的 Internet 信息服务的内置帐户 (在白吃点就是启 ...

  8. ZRender实现粒子网格动画实战

    注:本博文代码基于ZRender 3.4.3版本号开发,相应版本号库地址:ZRender 库. 效果 实现分析 通过上面显示的效果图,能够看出,这样的效果就是在Canvas中生成多个可移动的点,然后依 ...

  9. <LeetCode OJ> 83. Remove Duplicates from Sorted List

    83. Remove Duplicates from Sorted List Total Accepted: 94387 Total Submissions: 264227 Difficulty: E ...

  10. JAVA Eclipse 出现 load id=gralloc != hmi-id=gralloc怎么办

    一般是应用程序权限导致的,在Manifest.xml文件中,targetSdkVersion设置不正确,你可以直接删掉这个信息