1.J
ava
虚拟机
java
虚拟机是一个想象中的机器
,
在实际的计算机上通过软件模拟来实现。
java
虚拟机有自己想象中的硬件
,
如处理器、堆栈、寄存器
等
,
还具有相应的指令系统。
2.
Java
虚拟机体系结构
java
虚拟机由五个部分组成
:
一组指令集、一组寄存器、一个栈、一个无用单元收集堆
(garbage-collected-heap)
、一个方法区域。
这五部分是
java
虚拟机的逻辑成份
,
不依赖任何实现技术或组织方式
,
但它们的功能必须在真实机器上以某种方式实现。
3.
Java
虚拟机区别活动对象与垃圾的方法
Java
虚拟机可以有两种不同的方法来区别活动对象与垃圾:引用计数
(Reference Counting)
与跟踪
(Tracing)
3.1
采用
Reference Counting
的垃圾回收器
对于采用
Reference Counting
的垃圾回收器,系统为堆上每一个对象都维护一个计数器,当一个对象被创建并且别引用时,这个计数就被置为
1
。当有新的变量引用该对象,计数器进行自加运算。当一个引用超出作用范围或者被赋予新值的时候,计数器进行自减运算。引用计数为
0
的对象,会被作为垃圾回收。当一个对象被回收,该对象所引用的对象的引用计数都会相应减少,因而,一个对象的回收有时会引起其它对象的回收。
Reference Counting
方式的垃圾回收器,好处在于可以在很短的时间内运行
,不会长时间的中断普通的程序运行,因而在
RealTime
的系统中应用较为普遍。
Reference Counting
方式的垃圾回收器,问题在于无法识别循环引用,比如父类对象还有子类引用的情况,即便父类和子类都已经不再能被访问到
(unreachable)
,引用计数也把它们清除。另外一个问题是引用计数器的加减运算会增加系统的计算开销。
3.2
采用
Tracing
的垃圾回收器
采用
Tracing
的垃圾回收器,遍历由根节点
(root nodes)
出发的引用关系图。在遍历过程中遇到的对象,就被标记为活动。标记既可以是对应对象中的某一个标志,也可以是独立的位图中的标志。当遍历完成以后,那些没有被标记的对象,就被作为垃圾回收了。
最基本
Tracing
算法是
"Mark and Sweep"
垃圾回收器的另外一个责任是清除堆上的碎片
(Fragmentation)
。对于
Mark and Sweep
的垃圾回收器通常有两种实现方法来减少堆上的碎片:
压缩
(Compacting)
和拷贝
(Copying)
。
4.
基本回收算法
4.1
引用计数(
Reference Counting
)
比较古老的回收算法。原理是此对象有一个引用,即增加一个计数,删除一个引用则减少一个计数。垃圾回收时,只用收集计数为
0
的对象。此算法最致命的是无法处理循环引用的问题。
4.2
标记
-
清除(
Mark-Sweep
)
此算法执行分两阶段。第一阶段从引用根节点开始标记所有被引用的对象,第二阶段遍历整个堆,把未标记的对象清除。此算法需要暂停整个应用,同时,会产生内存碎片。
4.3
复制(
Copying
)
此算法把内存空间划为两个相等的区域,每次只使用其中一个区域。垃圾回收时,遍历当前使用区域,把正在使用中的对象复制到另外一个区域中。次算法每次只处理正在使用中的对象,因此复制成本比较小,同时复制过去以后还能进行相应的内存整理,不过出现
“
碎片
”
问题。当然,此算法的缺点也是很明显的,就是需要两倍内存空间。
4.4
标记-
整理(Mark-Compact
)
此算法结合了
“
标记
-
清除
”
和
“
复制
”
两个算法的优点。也是分两阶段,第一阶段从根节点开始标记所有被引用对象,第二阶段遍历整个堆,把清除未标记对象并且把存活对象
“
压缩
”
到堆的其中一块,按顺序排放。此算法避免了
“
标记
-
清除
”
的碎片问题,同时也避免了
“
复制
”
算法的空间问题。
4.5
增量收集(
Incremental Collecting
)
实施垃圾回收算法,即:在应用进行的同时进行垃圾回收。不知道什么原因
JDK5.0
中的收集器没有使用这种算法的。
4.6
分代(
Generational Collecting
)
基于对对象生命周期分析后得出的垃圾回收算法。把对象分为年青代、年老代、持久代,对不同生命周期的对象使用不同的算法(上述方式中的一个)进行回收。现在的垃圾回收器(从
J2SE1.2
开始)都是使用此算法的。
Java
堆分可为
Young(
年轻代
)
,
Tenured(
年老代
)
,
Perm(
持久代
)
三个部分,下面是各代的分布情况。
l
Young
(年轻代)
年轻代分三个区。一个
Eden
区,两个
Survivor
区
。大部分对象在
Eden
区中生成。当
Eden
区满时,还存活的对象将被复制到
Survivor
区(两个中的一个),当这个
Survivor
区满时,此区的存活对象将被复制到另外一个
Survivor
区,当这个
Survivor
去也满了的时候,从第一个
Survivor
区复制过来的并且此时还存活的对象,将被复制
“
年老区
(Tenured)”
。需要注意,
Survivor
的两个区是对称的,没先后关系,所以同一个区中可能同时存在从
Eden
复制过来对象,和从前一个
Survivor
复制过来的对象,而复制到年老区的只有从第一个
Survivor
去过来的对象。而且,
Survivor
区总有一个是空的。
l
Tenured
(年老代)
年老代存放从年轻代存活的对象。一般来说年老代存放的都是生命期较长的对象。
l
Perm
(持久代)
用于存放静态文件,如今
Java
类、方法等。持久代对垃圾回收没有显著影响,但是有些应用可能动态生成或者调用一些
class
,例如
Hibernate
等,在这种时候需要设置一个比较大的持久代空间来存放这些运行过程中新增的类。持久代大小通过
-XX:MaxPermSize=<N>
进行设置。
4.6.2
分代垃圾回收演示过程:
5.
垃圾回收器
5.1
发生垃圾回收的两种类型:
Scavengc GC
和
Full GC
。
一般情况下,当新对象生成,并且在
Eden
申请空间失败时,就好触发
Scavenge GC
,堆
Eden
区域进行
GC
,清除非存活对象,并且把尚且存活的对象移动到
Survivor
区。然后整理
Survivor
的两个区。
对整个堆进行整理,包括
Young
、
Tenured
和
Perm
。
Full
GC
比
Scavenge GC
要慢,因此应该尽可能减少
Full GC
。有如下原因可能导致
Full GC
:
l
Tenured
被写满
l
Perm
域被写满
l
System.gc()
被显示调用
l
上一次
GC
之后
Heap
的各域分配策略动态变化
5.2
使用的垃圾收集器种类
目前所使用的垃圾收集器主要有三种:串行收集器、并行收集器、并发收集器。
l
串行收集器
使用单线程处理所有垃圾回收工作,因为无需多线程交互,所以效率比较高。但是,也无法使用多处理器的优势,所以此收集器适合单处理器机器。当然,此收集器也可以用在小数据量(
100M
左右)情况下的多处理器机器上。可以使用
-XX:+UseSerialGC
打开。
l
并行收集器
对年轻代进行并行垃圾回收,因此可以减少垃圾回收时间。一般在多线程多处理器机器上使用。使用
-XX:+UseParallelGC.
打开。并行收集器在
J2SE5.0
第六
6
更新上引入,在
Java SE6.0
中进行了增强,可以对年老代进行并行收集。如果年老代不使用并发收集的话,是使用单线程进行垃圾回收,因此会制约扩展能力。使用
-XX:+UseParallelOldGC
打开。使用
-XX:ParallelGCThreads=<N>
设置并行垃圾回收的线程数。此值可以设置与机器处理器数量相等。
此收集器可以进行如下配置:
最大垃圾回收暂停
:
指定垃圾回收时的最长暂停时间,通过
-XX:MaxGCPauseMillis=<N>
指定。
<N>
为毫秒
.
如果指定了此值的话,堆大小和垃圾回收相关参数会进行调整以达到指定值。设定此值可能会减少应用的吞吐量。
吞吐量
:
吞吐量为垃圾回收时间与非垃圾回收时间的比值,通过
-XX:GCTimeRatio=<N>
来设定,公式为
1/
(
1+N
)。例如,
-XX:GCTimeRatio=19
时,表示
5%
的时间用于垃圾回收。默认情况为
99
,即
1%
的时间用于垃圾回收。
l
并发收集器
可以保证大部分工作都并发进行(应用不停止),垃圾回收只暂停很少的时间,此收集器适合对响应时间要求比较高的中、大规模应用。使用
-XX:+UseConcMarkSweepGC
打开。
并发收集器主要减少年老代的暂停时间,他在应用不停止的情况下使用独立的垃圾回收线程,跟踪可达对象。在每个年老代垃圾回收周期中,在收集初期并发收集器会对整个应用进行简短的暂停,在收集中还会再暂停一次。第二次暂停会比第一次稍长,在此过程中多个线程同时进行垃圾回收工作。
并发收集器使用处理器换来短暂的停顿时间。在一个
N
个处理器的系统上,并发收集部分使用
K/N
个可用处理器进行回收,一般情况下
1<=K<=N/4
。
在只有一个处理器的主机上使用并发收集器,设置为
incremental mode
模式也可获得较短的停顿时间。
浮动垃圾:由于在应用运行的同时进行垃圾回收,所以有些垃圾可能在垃圾回收进行完成时产生,这样就造成了
“Floating Garbage”
,这些垃圾需要在下次垃圾回收周期时才能回收掉。所以,并发收集器一般需要
20%
的预留空间用于这些浮动垃圾。
Concurrent
Mode Failure
:并发收集器在应用运行时进行收集,所以需要保证堆在垃圾回收的这段时间有足够的空间供程序使用,否则,垃圾回收还未完成,堆空间先满了。这种情况下将会发生
“
并发模式失败
”
,此时整个应用将会暂停,进行垃圾回收。
启动并发收集器:因为并发收集在应用运行时进行收集,所以必须保证收集完成之前有足够的内存空间供程序使用,否则会出现
“Concurrent Mode Failure”
。通过设置
-XX:CMSInitiatingOccupancyFraction=<N>
指定还有多少剩余堆时开始执行并发收集
分享到:
相关推荐
《深入理解Java虚拟机1》是一本探讨Java技术体系核心组成部分的著作,主要关注Java虚拟机(JVM)的相关知识。Java技术体系由Java虚拟机、Java类库、Java编程语言以及第三方Java框架构成。JVM作为这个体系的核心,为...
深入 Java 虚拟机.pdf Java 虚拟机(Java Virtual Machine,JVM)是 Java 语言的 runtime 环境,是 Java 程序执行的核心组件。它提供了一个平台无关的环境,允许 Java 程序在不同的操作系统和硬件平台上运行。 一...
第1章从宏观的角度介绍了Java虚拟机与Java的关系及发展历程;第2章概述Java虚拟机的整体架构,包括class文件格式、数据类型、原始类型、引用类型、运行时数据区、栈帧、浮点算法、异常等,这对理解本书后面的内容有...
Java虚拟机规范 Java SE 8版-带目录-pdf,本书完整而准确地阐释了Java虚拟机各方面的细节,围绕Java虚拟机整体架构、编译器、class文件格式、加载、链接与初始化、指令集等核心主题对Java虚拟机进行全面而深入的分析...
第1章 :简单地介绍了Java虚拟机的历史并吹捧了←_← 一下Java的平台无关性(一次编译,到处运行); 第2章:概览Java虚拟机整体架构; 第3章:介绍如何将Java语言编写的程序转换为虚拟机指令集; 第4章:定义...
本书摒弃了传统的以解读枯燥的Java虚拟机规范文档和分析繁琐的Java虚拟机源代码的方式来讲解Java虚拟机,取而代之的是,以实践的方式,引导读者如何从零开始构建和实现一个Java虚拟机,整个过程不仅能让读者做到对...
Java虚拟机(JVM)是Java编程语言的核心组成部分,它是一种抽象的计算设备,能够运行Java字节码。Java虚拟机规范(Java SE 7版)是定义JVM行为的官方文档,确保所有Java平台的实现遵循相同的规则,以提供跨平台的...
Java虚拟机(JVM)是Java程序运行的基础,它负责执行Java字节码,提供了一个与平台无关的执行环境。JVM规范定义了JVM的结构、指令集和运行时数据区,以及如何执行指令和处理异常。自1999年以来,JVM规范经历了多次...
java虚拟机规范,高清PDF版本,含有目录结构:第一章:引言; 第二章:java虚拟结构(运行时区域内存:寄存器,java虚拟机栈,java堆,方法去,运行时常量池,本地方法栈); 第三章:为java虚拟机编译; 第四章:...
Java虚拟机(JVM)是实现Java技术的关键组件,它为Java程序提供了一个运行环境。Java程序在编写后会被编译成一种称为字节码的中间表示形式,这种字节码可以跨平台运行,因为JVM负责将字节码转换成机器代码。JVM的...
Java虚拟机(Java Virtual Machine,简称JVM)是Java编程语言的核心组成部分,它是一个用于执行Java字节码的软件或硬件设备。Java程序在编译时并不直接转化为机器语言,而是转化为中间代码,即字节码。JVM的作用就是...
### Java虚拟机规范(JVM)概览 #### 核心概念与重要性 《Java虚拟机规范(JavaSE7版)》是理解Java虚拟机(JVM)运作机制的基石,由Tim Lindholm、Frank Yellin、Gilad Bracha和Alex Buckley等人撰写,后由周志明、...
Java虚拟机(JVM)是Java编程语言的核心组成部分,它为Java程序提供了跨平台的运行环境。Java程序在编写完成后,会被编译成字节码(.class文件),这些字节码可以在任何装有JVM的系统上运行,实现了“一次编写,到处...
随着越来越多的第三方语言(Groovy、Scala、JRuby等)在Java虚拟机上运行,Java...《实战Java虚拟机——JVM故障诊断与性能优化》将通过200余示例详细介绍Java虚拟机中的各种参数配置、故障排查、性能监控以及性能优化。
第1章从宏观的角度介绍了Java虚拟机与Java的关系及发展历程;第2章概述Java虚拟机的整体架构,包括class文件格式、数据类型、原始类型、引用类型、运行时数据区、栈帧、浮点算法、异常等,这对理解本书后面的内容有...
Java虚拟机(JVM,Java Virtual Machine)是Java平台的核心组成部分,它负责执行Java程序,为Java代码提供了跨平台的运行环境。Java虚拟机的概念始于Sun Microsystems,现在由Oracle公司继续发展和维护。JVM的设计...