Java虚拟机之垃圾回收详解一html
Java技术和JVM(Java虚拟机)java
1、Java技术概述:web
Java是一门编程语言,是一种计算平台,是SUN公司于1995年首次发布。它是Java程序的技术基础,这些程序包括:实用程序、游戏、商业应用程序。在全世界范围内,Java运行在超过数十亿台我的计算机上,数十亿台设备上,还包括手机和电视设备。Java由一系列的关键组件做为一个总体构建出了Java平台。express
Java Runtime Edition编程
当你下载Java,你就获得了Java运行环境(JRE)。JRE包括Java虚拟机(JVM)、Java平台核心类文件、支持Java平台的类库。对于运行Java程序,这三个部分都是必须的。安全
Java Programming Language网络
Java是一门面向对象编程语言,具备如下特性:数据结构
JDK是Java程序开发的工具集,你可使用它编译用Java语言编写的程序,而后在JVM上运行你编写的程序。另外,JDK还提供打包和发布程序功能。多线程
JDK和JRE共享Java程序编程接口(Java API)。Java API 是Java供开发人员编写Java程序时使用的预打包库,Java API 提供工具使得Java程序开发更容易,好比字符串操做、日期/时间处理、网络编程、实现数据结构(例如:链表,maps、堆栈、队列)。架构
JVM是一台抽象的计算机。JVM是一个程序,这个程序看起来像是一台计算机,它能够执行程序。经过这种方式,Java程序的编写使用了相同的接口和库。每种JVM对应着特定的操做系统,将Java指令转换为能够在该操做系统上运行的指令或是命令。经过这种方式,Java程序实现了平台独立性。
其实JVM对Java语言是一无所知的,JVM能识别的是特殊的二进制格式和类文件格式。一个类文件包含了JVM指令或者字节码、符号表、以及一些辅助信息。
为了安全起见,JVM对于类文件中的编码的语法和结构有严格的规定。However, any language with functionality that can be expressed in terms of a valid class file can be hosted by the Java virtual machine. Attracted by a generally available, machine-independent platform, implementors of other languages can turn to the Java virtual machine as a delivery vehicle for their languages.(这几句话不太理解,暂时放在这里吧!)
2、探索JVM的结构:
HotSpot JVM 的架构使得它能支持强大的基础特性和性能,而且可以实现高性能和较好的扩展性。例如,HotSpot JVM JIT编译器能够在编译时进行动态优化。换言之,这些编译器能够在Java程序运行时作出最优选择,生成高性能的本地主机指令以适应本地主机系统架构。另外,它的运行环境和多线程垃圾回收变的愈来愈成熟,愈来愈具备持久的工程性,HotSpot JVM 在大型计算机系统上也表现出可扩展性。
JVM 主要的组件包括:类加载器、运行时数据区、执行引擎。
JVM 跟性能相关的主要组件以下图中高亮部分。
JVM中有三个组件和性能密切相关。堆是对象数据存储区,这个区域由垃圾回收管理。大多数调试性能和堆的大小有关,也和选择合适的垃圾回收器相关。JIT 编译器对性能影响很大,但不多须要调试新版本的JVM。
垃圾回收概述
什么是垃圾自动回收?
垃圾自动回收是一个查看堆内存的过程,在此过程当中辨识出那些对象仍在使用,哪些对象再也不使用而后删除不会再被使用的对象。一个的对象或者对象引用正在使用的意思是程序的某个部分仍然保持着一个指针指向这个对象或对象的引用。一个再也不使用的对象或引用意思是再也不被程序的任何部分所引用。因此未被引用的对象所占的内存空间是能够被回收的。
在C语言中,分配和回收内存是用户手动操做的,在Java语言中,内存回收是由垃圾回收器自动完成的。垃圾回收基本过程:
步骤1:标记
第一步是标记。这个过程是垃圾回收器标记出那片内存在使用,那片不在使用。
蓝色表示被引用对象,金色表示未被引用对象。在作出这个标记阶段,全部对象都被扫描一遍(如此操做,效率必然很低啊)。若是系统中的全部对象都须要被扫描一遍是一个很耗时的过程。
步骤2:普通删除
普通删除是删除未被引用的对象,保留被引用对象而且使用指针指向删除后的空闲空间。
内存回收器保存了空闲块的地址引用来分配给新的对象使用。
步骤2a:压缩删除
为了进一步改善性能,在删除未被引用对象后,压缩空间里剩余的被引用对象。经过移动被引用对象在一块儿,使得空闲空间聚合在一块儿,更便于新的内存分配。
为何分代垃圾回收?
如以前所述,标记和压缩JVM中的全部对象是效率很低的。随着愈来愈多的对象被分配空间,对象链表愈来愈大使得垃圾回收时间愈来愈长。然而,根据对程序分析的经验代表,大多数对象的生命周期很短。
以下图数据所示,Y轴表明被分配的字节数,X表明随时间推移被回收的字节数。
如你所见,随着时间推移保留在内存中的对象愈来愈少。实际上,大多数对象的生命周期都很短,如图所示,X轴左侧有很大的值,短期内巨幅降低。
JVM中的分代
从对象分配的动做中获得的信息能够用来改善JVM的性能。所以,堆能够被分为更小的块或是分代。堆可分红:新生代、老或者是年老代和永久代。
新生代存储了全部的新建对象。当新生代溢出时,触发minor garbage collection。在假定对象高死亡率的状况下,Minor collections 是最优的垃圾回收选择。一个充满废弃对象的新生代内存空间回收很快。某些存留的对象年龄增长而后移动到Old Gerneration。
Stop the World Event - 全部 minor garbage collection 都是 ”stop the world“ 事件,便是全部的线程都会被中止直到垃圾回收操做完成。
Old Gerneration 用来存储长时间存活的对象。典型的,JVM会为新生代设置一个阈值,当新生代年龄达到此阈值,此对象会被移动到old generation。即便old generation 也须要被回收。old generation 被回收事件叫作 major garbage collection 。
major garbage collection 也是 stop the world事件。一般 major garbage collection 会更慢,该过程包括全部的存活对象。因此对于响应式的程序,major garbage collection 须要最小化。一样须要注意,major garbage collection 所引发的 stop the world事件的时间长度受Old Gerneration空间所采用的垃圾回收器的类别影响。
永久代存储了元数据,这些元数据是JVM用来描述程序中所使用的类文件和方法的。old Gerneration 存储了JVM运行时所依赖的类。另外,Java SE 类库文件和方法也可能存储在这里。
类文件也可能被回收,若是JVM发现他们再也不被须要,回收的空间用于存储哪些程序所必须的类。全部的垃圾回收都会对永久代空间进行收集。
分代垃圾收集过程
既然已经理解了堆分代的缘由,如今来看一下不一样空间如何相互影响的。下图描述了JVM中对象分配内存和对象老龄化的过程:
1.首先,任何新对象分配到eden 空间。两个survivor空间开始时均为空。
2.当eden 空间溢出时,minor garbage collection 被触发。
3.被引用的对象被移动到第一个survivor空间。当eden 空间被清空时未被引用的对象被删除。
4.下一次minor GC时,eden空间执行相同动做。未被引用对象被删除,被引用对象移动到一个survivor空间。然而,在这种状况下,被引用对象移动到S1中。另外,由上次minor GC产生的存储在S0中的对象年龄增长而且移动到S1中。一旦全部存活对象都被移动到S1中,S0和eden空间都被清空。注意到,如今在survivor空间中有不一样年龄的对象。
5.下一次minor GC时,重复一样的过程。然而,此次survivor空间互换了。被引用对象移动到了S0。存活对象年龄增长,eden 和 S1 被清空。
6.下面说明的是一次升级过程。在一次minor GC以后,当老年代的对象的年龄达到特定年龄阈(这个例子中阈值是8)时,这些对象重新生代升级成ld generation。
7.随着minor GC继续发生,对象继续被移动到old generation 空间。
8.young generation 通过屡次的minor GC 以后,最终,major GC 会在 old generation 上执行以清理并压缩此内存空间。
总结:以上就是垃圾回收的基本原理和过程,有错误之处请指正!
附:http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html