JVM的垃圾回收机制小读
jvm的gc原理

jvm的gc原理JVM的GC原理一、概述JVM(Java虚拟机)是Java程序运行的环境,其中最重要的组成部分之一就是垃圾回收(Garbage Collection,简称GC)机制。
GC的作用是自动管理程序中的内存,及时释放不再使用的对象,以避免内存泄漏和内存溢出的问题。
本文将对JVM的GC原理进行详细介绍。
二、垃圾回收算法1. 标记-清除算法标记-清除算法是最基本的垃圾回收算法之一。
它的过程分为两个阶段:标记阶段和清除阶段。
在标记阶段,GC会从根节点(一般是程序中的静态变量和栈中的引用)开始,递归地遍历对象图,标记出所有被引用的对象。
在清除阶段,GC会遍历整个堆,清除所有未被标记的对象。
2. 复制算法复制算法是针对标记-清除算法的改进。
它将堆分为两个区域,每次只使用其中一个区域。
当一个区域的对象被标记后,将其复制到另一个区域中,然后清除原来的区域。
这样可以解决碎片问题,但是需要额外的空间来存储复制的对象。
3. 标记-整理算法标记-整理算法是对标记-清除算法的改进。
它的过程与标记-清除算法类似,但是在清除阶段,标记-整理算法会将存活的对象向一端移动,然后清除边界外的所有对象。
这样可以解决碎片问题,并且不需要额外的空间。
4. 分代算法分代算法是针对对象的生命周期不同而提出的。
一般来说,对象的生命周期可以分为年轻代和老年代。
年轻代中的对象生命周期较短,老年代中的对象生命周期较长。
分代算法将堆分为年轻代和老年代两个区域,分别采用不同的垃圾回收算法。
年轻代一般使用复制算法,老年代一般使用标记-清除算法或标记-整理算法。
三、GC的执行过程1. 初始标记初始标记阶段是GC的第一步,它的目的是标记出所有的根对象,并且停止所有的应用线程。
这个过程是短暂的,因为只需要标记出与根对象直接关联的对象。
2. 并发标记并发标记阶段是GC的核心步骤,它的目的是通过并发执行来标记出所有的存活对象。
在这个阶段,GC会遍历整个堆,标记出与根对象直接或间接关联的存活对象。
简单谈谈对GC垃圾回收的通俗理解

简单谈谈对GC垃圾回收的通俗理解简单谈谈对GC垃圾回收的通俗理解⽂章简介《简单谈谈对GC垃圾回收的理解》是我的第⼀篇博客,了解并学习了JVM的垃圾回收机制后,把⾃⼰的⼀些理解记录下来,通过输出博客的⽅式来沉淀,我觉得是⼀个不错的⽅式!垃圾回收是指什么所谓的垃圾,顾名思义,就是指的在程序运⾏的过程中,有类的诞⽣、初始化、销毁,在这⼀系列的过程中,我们的程序⾃然会产⽣⼀些已经消亡的,不需要的类、实例等等。
⽽这些对于程序不需要的东西或者阻碍程序正常运⾏的东西就是垃圾。
⽽垃圾回收指的就是将这些垃圾从我们程序运⾏的环境中清除出去,⾄于这些垃圾会去向哪⾥,⾃然是不需要我们去关⼼的,毕竟你也从未关⼼过垃圾收集车 将垃圾运往何处!为什么需要垃圾回收我们都知道,⼩区的垃圾回收车 每天都会将垃圾集中运⾛处理,还⼩区⼀个⼲净舒适的环境。
那么同样,程序的运⾏也需要⼀个畅通⽆阻的环境。
如果垃圾过多,可能导致程序运⾏时间变长,就像我们的电脑C盘空间不⾜的时候,电脑不仅运⾏缓慢,还会出现死机、蓝屏等恶况!程序中⽐较经典的因为垃圾过多导致的错误就有OOM(ng.OutOfMemoryError)。
OOM 内存不⾜官⽅语⾔是这样描述的:当Java虚拟机由于内存不⾜⽽⽆法分配对象,并且垃圾回收器⽆法再提供更多内存时,抛出该异常。
通俗来说,就是内存满了,爆了。
⽽我们知道,java中错误(Error)和异常(Exception)是不同的。
异常还可以被捕获、抛出来通过程序代码来处理,但是错误已经严重到不⾜以被应⽤处理,会导致程序直接崩溃停⽌!在真实项⽬中这样的情况肯定是不允许发⽣的。
那么我们可以分析⼀下导致内存不⾜的原因!⽆外乎有以下两点:分配到的内存太少。
程序使⽤的太多。
分配太少:我们知道,虚拟机可以使⽤的内存也是有个限度的,当被分配的内存⼤⼩完全不够⽀持我们程序正常运⾏就会OOM。
我们可以通过以下代码查看JVM初始化的总内存⼤⼩和JVM试图使⽤的最⼤内存。
javaGC垃圾回收机制G1、CMS

javaGC垃圾回收机制G1、CMSCMS(Concurrent Mark-Sweep)是以牺牲吞吐量为代价来获得最短回收停顿时间。
对于要求服务器响应速度的应⽤上,这种垃圾回收器⾮常适合。
在启动JVM参数加上-XX:+UseConcMarkSweepGC ,这个参数表⽰对于⽼年代的回收采⽤CMS。
CMS采⽤的基础算法是:标记—清除。
使⽤场景:1、应⽤程序对停顿⽐较敏感,并且在应⽤程序运⾏的时候可以提供更⼤的内存和更多的CPU2、在JVM中,有相对较多存活时间较长的对象(⽼年代⽐较⼤)会更适合使⽤CMS。
为解决CMS算法产⽣空间碎⽚和其它⼀系列的问题缺陷,HotSpot提供了另外⼀种垃圾回收策略,G1(Garbage First)算法,通过参数-XX:+UseG1GC来启⽤,该算法在JDK 7u4版本被正式推出,G1垃圾收集算法主要应⽤在多CPU⼤内存的服务中,在满⾜⾼吞吐量的同时,竟可能的满⾜垃圾回收时的暂停时间,下⾯是官⽅介绍:The Garbage-First (G1) collector is a server-style garbage collector, targeted for multi-processor machines with large memories.It meets garbage collection (GC) pause time goals with a high probability, while achieving high throughput. The G1 garbagecollector is fully supported in Oracle JDK 7 update 4 and later releases. The G1 collector is designed for applications that:Can operate concurrently with applications threads like the CMS collector.Compact free space without lengthy GC induced pause times.Need more predictable GC pause durations.Do not want to sacrifice a lot of throughput performance.Do not require a much larger Java heap.G1采⽤了另外⼀种完全不同的⽅式组织堆内存,堆内存被划分为多个⼤⼩相等的内存块(Region),每个Region是逻辑连续的⼀段内存,G1中提供了三种模式垃圾回收模式,young gc、mixed gc 和 full gc,在不同的条件下被触发。
java自动垃圾回收机制

java⾃动垃圾回收机制前⾔:相⽐C++,java做的⼀⼤改进是将复杂的内存管理抽离出来交给jvm去处理,让码农不再时刻盯着内存泄漏的问题,可以更专注于业务逻辑的开发。
java的GC机制是和其内存模型相关联的,⽽GC的核⼼内存区域是内存中的堆区。
java堆区按对象的存活时间被分为了年轻代(eden区+s0区+s1区)和⽼年代(tentired区),java堆的按代区分其实是为了其垃圾回收的分代收集机制打开了⽅便之门。
java的GC收集器会在不同的分代上使⽤不同的垃圾收集策略。
GC其实主要需要解决两个问题:哪些是垃圾?如何清理垃圾?在解决这两个问题上涉及到下⾯的⽅法论:1.垃圾对象判定⽅法引⽤计数法:在C++的智能指针中使⽤了这种⽅式去做内存的⾃动回收。
即在对象⽣成时维护⼀个对该对象引⽤次数的计数器,对象初次⽣成时计数器值为1,每增加⼀个到该对象的引⽤,计数器加1,每减少⼀个引⽤(如引⽤变量赋值null,或引⽤变量离开作⽤域),计数器减1,计数器为零时,对象内存会被⾃动回收。
该⽅法的问题是存在内存泄漏的隐患,如对象相互引⽤、循环引⽤等情况相互引⽤:public class ReferenceCountingGc {Object instance = null;public static void main(String[] args) {ReferenceCountingGc objA = new ReferenceCountingGc();ReferenceCountingGc objB = new ReferenceCountingGc();objA.instance = objB;objB.instance = objA;objA = null;objB = null;}} 例⼦中两个new出来的对象ReferenceCountingGc由于通过内部的变量instance引⽤着对⽅,两个对象的引⽤计数都为1。
面试谈jvm原理

面试谈jvm原理Java虚拟机(JVM)是Java语言运行的基础。
JVM具有封装性、跨平台性、高度优化和可扩展性等特点,是Java应用程序的核心。
在Java的诞生初期,由于硬件环境和操作系统制约,JVM起到了垫底的作用。
而今天,JVM已经成为Java 运行效率和安全性的保障。
下面是一些我认为JVM原理面试时可能会涉及的重点:1. JVM的内存模型:JVM将内存分为堆内存和栈内存,堆内存用于存储对象实例和数组,而栈内存则用于存储方法的执行状态。
同时,JVM还有方法区和永久代的概念。
这些内存区域的大小和分配情况会影响JVM的性能和稳定性。
2. 垃圾回收机制:JVM的内存管理包括垃圾回收机制和内存分配机制。
垃圾回收机制是JVM实现自动内存管理的核心,JVM会周期性地扫描堆内存中没有被引用的对象,并自动回收它们所占用的内存。
垃圾回收机制常用的算法包括标记清除、复制和标记整理等。
3. 类加载机制:Java程序在运行时,需要将类文件中的二进制数据加载到JVM 中,才能执行相应的操作。
类加载机制将类文件加载到JVM中,并将它们解析为Java类。
类加载机制包括三个阶段:加载、链接和初始化。
4. JIT编译器:JIT(Just In Time)编译器是JVM在运行时动态优化的关键组件。
JIT编译器可以在程序运行时,根据代码的执行情况,生成本地机器代码,以提高程序的效率。
5. JVM调优:JVM的性能和稳定性很大程度上取决于JVM参数的设置和调整。
面试时,可能会涉及到如何根据系统的特点和需求,设置JVM参数以达到最佳性能和稳定性的问题。
总之,有关JVM原理的面试问题,往往涉及到JVM的内存模型、垃圾回收机制、类加载机制、JIT编译器和JVM调优等方面。
需要候选人对这些方面有比较深入的了解。
垃圾回收机制

垃圾回收机制垃圾回收是计算机科学中一种重要的机制,用于回收和释放程序中不再使用的内存空间,以提高系统的效率和性能。
1. 什么是垃圾回收机制?垃圾回收是一种自动化的内存管理技术,用于检测和回收程序中不再可用的内存对象。
它可以分析程序的运行时行为,识别不再被引用的对象,并将其释放以供其他程序使用。
2. 垃圾回收的优点- 减少内存泄漏:垃圾回收可以识别并回收不再使用的内存对象,从而减少内存泄漏的风险。
- 提高性能:回收不再使用的内存可以释放系统资源,提高程序的运行效率和响应速度。
- 简化编程:垃圾回收可以减少程序员手动管理内存的工作量,使编程更加简单和可靠。
3. 垃圾回收的实现方式垃圾回收机制可以通过以下几种方式来实现:- 引用计数:每个对象都维护一个引用计数器,当引用计数为零时,认为对象不再需要,可以进行回收。
- 标记-清除:通过标记所有可达对象,然后清除不可达对象来进行回收。
- 复制式垃圾回收:将内存分为两个区域,一部分为活跃对象,另一部分为闲置对象。
当活跃对象占满时,将活跃对象复制到闲置对象区域,然后清除活跃对象的内存。
- 分代式垃圾回收:根据对象的存活时间将内存分为多个代,然后对不同代进行不同的垃圾回收策略。
4. 垃圾回收的挑战垃圾回收虽然带来了许多优点,但也面临一些挑战:- 停顿时间:垃圾回收会导致程序的停顿,影响系统的实时性能。
- 资源消耗:垃圾回收需要消耗系统的资源,包括CPU和内存。
- 确定回收时机:确定内存对象是否不再使用是一个复杂的问题,需要进行准确的分析和判断。
5. 垃圾回收的最佳实践为了充分利用垃圾回收机制,以下是一些最佳实践:- 避免创建不必要的对象:尽量避免频繁创建和销毁对象,以减少垃圾的产生。
- 及时释放资源:在不再需要使用内存对象时,及时进行释放,以加快垃圾回收的速度。
- 使用合适的数据结构:选择合适的数据结构可以减少垃圾回收的复杂性和开销。
结论垃圾回收机制是一种重要的内存管理技术,可以提高系统的性能和可靠性。
垃圾回收机制的原理

垃圾回收机制的原理随着计算机领域的不断发展,我们的应用程序正在变得越来越庞大和复杂。
而这些应用程序一旦开始运行,就会占用大量的系统内存。
为了确保计算机系统的稳定运行,我们需要一种垃圾回收机制来确保内存资源的有效管理。
本文将介绍垃圾回收机制的原理以及其在计算机系统中的应用。
1. 垃圾回收机制垃圾回收机制是一种自动内存管理机制,它会扫描内存中不再使用的对象并将其标记为“无用垃圾”。
这些“无用垃圾”对象然后被系统回收,以释放它们占用的内存资源。
在某些编程语言中,如Java和Python,垃圾回收机制是自动完成的,开发人员不需要手动清理内存。
在其他编程语言中,如C和C ++,开发人员需要手动释放不再使用的内存资源。
2. 垃圾回收算法垃圾回收算法是垃圾回收机制的核心。
垃圾回收算法通常使用两种基本方法: 引用计数和标记-清除。
2.1 引用计数引用计数算法是最简单的垃圾回收算法之一。
在这个算法中,编程语言会保持即将使用的每个对象的引用数量。
当引用数量降至零时,对象将被标记为垃圾并由垃圾回收机制自动回收。
尽管这种算法可能比较简单,但它容易陷入循环引用的问题,即两个或多个对象引用对方,而不消失引用。
因此,循环引用的对象不会被回收,这可能会导致内存泄漏。
2.2 标记-清除标记-清除算法是一种更复杂的垃圾回收算法,它由两个步骤组成。
首先,算法扫描内存中的所有对象,标记所有活动对象。
这些活动对象在程序中仍有引用。
然后,算法会清空未标记的对象,释放它们占用的内存资源。
这种算法能够解决引用计数的问题,但在大型内存中,扫描整个内存可能比较缓慢,影响系统的性能。
3. 垃圾回收机制的应用场景在大型应用程序中,使用垃圾回收机制来确保有效的内存管理非常重要。
垃圾回收机制能够避免内存泄漏等问题,保证系统的稳定运行。
垃圾回收机制的典型应用场景包括桌面应用程序和网络应用程序,如网站和服务器。
4. 总结垃圾回收机制是一种自动化的内存管理机制,它可以扫描内存中无用的对象,并释放它们占用的内存资源。
JVM垃圾回收之三色标记

JVM垃圾回收之三⾊标记三⾊标记法是⼀种垃圾回收法,它可以让JVM不发⽣或仅短时间发⽣STW(Stop The World),从⽽达到清除JVM内存垃圾的⽬的。
JVM中的CMS、G1垃圾回收器所使⽤垃圾回收算法即为三⾊标记法。
三⾊标记算法思想三⾊标记法将对象的颜⾊分为了⿊、灰、⽩,三种颜⾊。
⽩⾊:该对象没有被标记过。
(对象垃圾)灰⾊:该对象已经被标记过了,但该对象下的属性没有全被标记完。
(GC需要从此对象中去寻找垃圾)⿊⾊:该对象已经被标记过了,且该对象下的属性也全部都被标记过了。
(程序所需要的对象)算法流程从我们main⽅法的根对象(JVM中称为GC Root)开始沿着他们的对象向下查找,⽤⿊灰⽩的规则,标记出所有跟GC Root相连接的对象,扫描⼀遍结束后,⼀般需要进⾏⼀次短暂的STW(Stop The World),再次进⾏扫描,此时因为⿊⾊对象的属性都也已经被标记过了,所以只需找出灰⾊对象并顺着继续往下标记(且因为⼤部分的标记⼯作已经在第⼀次并发的时候发⽣了,所以灰⾊对象数量会很少,标记时间也会短很多), 此时程序继续执⾏,GC线程扫描所有的内存,找出扫描之后依旧被标记为⽩⾊的对象(垃圾),清除。
具体流程:⾸先创建三个集合:⽩、灰、⿊。
将所有对象放⼊⽩⾊集合中。
然后从根节点开始遍历所有对象(注意这⾥并不递归遍历),把遍历到的对象从⽩⾊集合放⼊灰⾊集合。
之后遍历灰⾊集合,将灰⾊对象引⽤的对象从⽩⾊集合放⼊灰⾊集合,之后将此灰⾊对象放⼊⿊⾊集合重复 4 直到灰⾊中⽆任何对象通过write-barrier检测对象有变化,重复以上操作收集所有⽩⾊对象(垃圾)三⾊标记存在问题浮动垃圾:并发标记的过程中,若⼀个已经被标记成⿊⾊或者灰⾊的对象,突然变成了垃圾,由于不会再对⿊⾊标记过的对象重新扫描,所以不会被发现,那么这个对象不是⽩⾊的但是不会被清除,重新标记也不能从GC Root中去找到,所以成为了浮动垃圾,浮动垃圾对系统的影响不⼤,留给下⼀次GC进⾏处理即可。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
JVM的垃圾回收机制小读技术2010-05-09 19:41:04 阅读20 评论2 字号:大中小订阅今天下午突然遇到了一个内存漏洞的问题,所以上网查了查,结果看到了一篇文章,说的是jvm的垃圾回收机制,下面粘过来,看了好久才看完的,说的思路有点含糊,还给带了点代码,这样还不错……对JVM的内存管理机制有加深了一层理解哈…………下面是那篇文章,喜欢的可以看看…………O(∩_∩)O…………Java的堆是一个运行时数据区,类的实例(对象)从中分配空间。
Java虚拟机(JVM)的堆中储存着正在运行的应用程序所建立的所有对象,这些对象通过new、newarray、anewarray和multianewarray等指令建立,但是它们不需要程序代码来显式地释放。
引言Java的堆是一个运行时数据区,类的实例(对象)从中分配空间。
Java虚拟机(JVM)的堆中储存着正在运行的应用程序所建立的所有对象,这些对象通过new、newarray、anewarray和multianewarray等指令建立,但是它们不需要程序代码来显式地释放。
一般来说,堆的是由垃圾回收来负责的,尽管JVM规范并不要求特殊的垃圾回收技术,甚至根本就不需要垃圾回收,但是由于内存的有限性,JVM在实现的时候都有一个由垃圾回收所管理的堆。
垃圾回收是一种动态存储管理技术,它自动地释放不再被程序引用的对象,按照特定的垃圾收集算法来实现资源自动回收的功能。
垃圾收集的意义在C++中,对象所占的内存在程序结束运行之前一直被占用,在明确释放之前不能分配给其它对象;而在Java中,当没有对象引用指向原先分配给某个对象的内存时,该内存便成为垃圾。
JVM的一个系统级线程会自动释放该内存块。
垃圾收集意味着程序不再需要的对象是"无用信息",这些信息将被丢弃。
当一个对象不再被引用的时候,内存回收它占领的空间,以便空间被后来的新对象使用。
事实上,除了释放没用的对象,垃圾收集也可以清除内存记录碎片。
由于创建对象和垃圾收集器释放丢弃对象所占的内存空间,内存会出现碎片。
碎片是分配给对象的内存块之间的空闲内存洞。
碎片整理将所占用的堆内存移到堆的一端,JVM将整理出的内存分配给新的对象。
垃圾收集能自动释放内存空间,减轻编程的负担。
这使Java 虚拟机具有一些优点。
首先,它能使编程效率提高。
在没有垃圾收集机制的时候,可能要花许多时间来解决一个难懂的存储器问题。
在用Java 语言编程的时候,靠垃圾收集机制可大大缩短时间。
其次是它保护程序的完整性,垃圾收集是Java语言安全性策略的一个重要部份。
垃圾收集的一个潜在的缺点是它的开销影响程序性能。
Java虚拟机必须追踪运行程序中有用的对象,而且最终释放没用的对象。
这一个过程需要花费处理器的时间。
其次垃圾收集算法的不完备性,早先采用的某些垃圾收集算法就不能保证100%收集到所有的废弃内存。
当然随着垃圾收集算法的不断改进以及软硬件运行效率的不断提升,这些问题都可以迎刃而解。
垃圾收集的算法分析Java语言规范没有明确地说明JVM使用哪种垃圾回收算法,但是任何一种垃圾收集算法一般要做2件基本的事情:(1)发现无用信息对象;(2)回收被无用对象占用的内存空间,使该空间可被程序再次使用。
大多数垃圾回收算法使用了根集(root set)这个概念;所谓根集就量正在执行的Java程序可以访问的引用变量的集合(包括局部变量、参数、类变量),程序可以使用引用变量访问对象的属性和调用对象的方法。
垃圾收集首选需要确定从根开始哪些是可达的和哪些是不可达的,从根集可达的对象都是活动对象,它们不能作为垃圾被回收,这也包括从根集间接可达的对象。
而根集通过任意路径不可达的对象符合垃圾收集的条件,应该被回收。
下面介绍几个常用的算法。
1、引用计数法(Reference Counting Collector)引用计数法是唯一没有使用根集的垃圾回收的法,该算法使用引用计数器来区分存活对象和不再使用的对象。
一般来说,堆中的每个对象对应一个引用计数器。
当每一次创建一个对象并赋给一个变量时,引用计数器置为1。
当对象被赋给任意变量时,引用计数器每次加1当对象出了作用域后(该对象丢弃不再使用),引用计数器减1,一旦引用计数器为0,对象就满足了垃圾收集的条件。
基于引用计数器的垃圾收集器运行较快,不会长时间中断程序执行,适宜地必须实时运行的程序。
但引用计数器增加了程序执行的开销,因为每次对象赋给新的变量,计数器加1,而每次现有对象出了作用域生,计数器减1。
2、tracing算法(Tracing Collector)tracing算法是为了解决引用计数法的问题而提出,它使用了根集的概念。
基于tracing算法的垃圾收集器从根集开始扫描,识别出哪些对象可达,哪些对象不可达,并用某种方式标记可达对象,例如对每个可达对象设置一个或多个位。
在扫描识别过程中,基于tracing算法的垃圾收集也称为标记和清除(mark-and-sweep)垃圾收集器.3、compacting算法(Compacting Collector)为了解决堆碎片问题,基于tracing的垃圾回收吸收了Compacting算法的思想,在清除的过程中,算法将所有的对象移到堆的一端,堆的另一端就变成了一个相邻的空闲内存区,收集器会对它移动的所有对象的所有引用进行更新,使得这些引用在新的位置能识别原来的对象。
在基于Compacting算法的收集器的实现中,一般增加句柄和句柄表。
4、copying算法(Coping Collector)该算法的提出是为了克服句柄的开销和解决堆碎片的垃圾回收。
它开始时把堆分成一个对象面和多个空闲面,程序从对象面为对象分配空间,当对象满了,基于coping算法的垃圾收集就从根集中扫描活动对象,并将每个活动对象复制到空闲面(使得活动对象所占的内存之间没有空闲洞),这样空闲面变成了对象面,原来的对象面变成了空闲面,程序会在新的对象面中分配内存。
一种典型的基于coping算法的垃圾回收是stop-and-copy算法,它将堆分成对象面和空闲区域面,在对象面与空闲区域面的切换过程中,程序暂停执行。
5、generation算法(Generational Collector)stop-and-copy垃圾收集器的一个缺陷是收集器必须复制所有的活动对象,这增加了程序等待时间,这是coping算法低效的原因。
在程序设计中有这样的规律:多数对象存在的时间比较短,少数的存在时间比较长。
因此,generation算法将堆分成两个或多个,每个子堆作为对象的一代(generation)。
由于多数对象存在的时间比较短,随着程序丢弃不使用的对象,垃圾收集器将从最年轻的子堆中收集这些对象。
在分代式的垃圾收集器运行后,上次运行存活下来的对象移到下一最高代的子堆中,由于老一代的子堆不会经常被回收,因而节省了时间。
6、adaptive算法(Adaptive Collector)在特定的情况下,一些垃圾收集算法会优于其它算法。
基于Adaptive算法的垃圾收集器就是监控当前堆的使用情况,并将选择适当算法的垃圾收集器。
透视Java垃圾回收1、命令行参数透视垃圾收集器的运行2、使用System.gc()可以不管JVM使用的是哪一种垃圾回收的算法,都可以请求Java的垃圾回收。
在命令行中有一个参数-verbosegc可以查看Java使用的堆内存的情况,它的格式如下:java -verbosegc classfile可以看个例子:class TestGC{public static void main(String[] args){new TestGC();System.gc();System.runFinalization();}}在这个例子中,一个新的对象被创建,由于它没有使用,所以该对象迅速地变为可达,程序编译后,执行命令:java -verbosegc TestGC 后结果为:[Full GC 168K->97K(1984K),0.0253873 secs]机器的环境为,Windows 2000 + JDK1.3.1,箭头前后的数据168K和97K分别表示垃圾收集GC前后所有存活对象使用的内存容量,说明有168K-97K=71K的对象容量被回收,括号内的数据1984K为堆内存的总容量,收集所需要的时间是0.0253873秒(这个时间在每次执行的时候会有所不同)。
3、finalize方法透视垃圾收集器的运行在JVM垃圾收集器收集一个对象之前,一般要求程序调用适当的方法释放资源,但在没有明确释放资源的情况下,Java提供了缺省机制来终止化该对象心释放资源,这个方法就是finalize()。
它的原型为:protected void finalize() throws Throwable在finalize()方法返回之后,对象消失,垃圾收集开始执行。
原型中的throws Throwable表示它可以抛出任何类型的异常。
之所以要使用finalize(),是由于有时需要采取与Java的普通方法不同的一种方法,通过分配内存来做一些具有C风格的事情。
这主要可以通过"固有方法"来进行,它是从Java里调用非Java方法的一种方式。
C和C++是目前唯一获得固有方法支持的语言。
但由于它们能调用通过其他语言编写的子程序,所以能够有效地调用任何东西。
在非Java代码内部,也许能调用C的malloc()系列函数,用它分配存储空间。
而且除非调用了free(),否则存储空间不会得到释放,从而造成内存"漏洞"的出现。
当然,free()是一个C和C++函数,所以我们需要在finalize()内部的一个固有方法中调用它。
也就是说我们不能过多地使用finalize(),它并不是进行普通清除工作的理想场所。
在普通的清除工作中,为清除一个对象,那个对象的用户必须在希望进行清除的地点调用一个清除方法。
这与C++"破坏器"的概念稍有抵触。
在C++中,所有对象都会破坏(清除)。
或者换句话说,所有对象都"应该"破坏。
若将C++对象创建成一个本地对象,比如在堆栈中创建(在Java中是不可能的),那么清除或破坏工作就会在"结束花括号"所代表的、创建这个对象的作用域的末尾进行。
若对象是用new创建的(类似于Java),那么当程序员调用C++的delete命令时(Java没有这个命令),就会调用相应的破坏器。
若程序员忘记了,那么永远不会调用破坏器,我们最终得到的将是一个内存"漏洞",另外还包括对象的其他部分永远不会得到清除。