本文目录一览

1,java的垃圾回收机制

Java的堆是一个运行时数据区,类的实例(对象)从中分配空间。Java虚拟机(JVM)的堆中储存着正在运行的应用程序所建立的所有对象,这些对象通过new、newarray、anewarray和multianewarray等指令建立,但是它们不需要程序代码来显式地释放。垃圾回收是一种动态存储管理技术,它自动地释放不再被程序引用的对象,按照特定的垃圾收集算法来实现资源自动回收的功能。
System.gc()
GC 是垃圾收集的意思(Gabage Collection),内存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃,Java 提供的GC 功能可以自动监测对象是否超过作用域从而达到自动回收内存的目的,Java 语言没有提供释放已分配内存的显示操作方法。Java 程序员不用担心内存管理,因为垃圾收集器会自动进行管理。要请求垃圾收集,可以调用下面的方法之一:System.gc() 或Runtime.getRuntime().gc() 。对于GC 来说,当程序员创建对象时,GC 就开始监控这个对象的地址、大小以及使用情况。通常,GC 采用有向图的方式记录和管理堆(heap)中的所有对象。通过这种方式确定哪些对象是"可达的",哪些对象是"不可达的"。当GC 确定一些对象为"不可达"时,GC 就有责任回收这些内存空间。可以。程序员可以手动执行System.gc(),通知GC 运行,但是Java 语言规范并不保证GC 一定会执行。

java的垃圾回收机制

2,java垃圾回收常用的两种方法是什么

java垃圾回收由java虚拟机自己调用,程序员不用管两种方法是 System.gc()Runtime.gc()Java堆的管理—垃圾回收提到一下几点,很不错,或许可以作为写程序时候的准则:(1)不要试图去假定垃圾收集发生的时间,这一切都是未知的。比如,方法中的一个临时对象在方法调用完毕后就变成了无用对象,这个时候它的内存就可以被释放。 (2)Java中提供了一些和垃圾收集打交道的类,而且提供了一种强行执行垃圾收集的方法--调用System.gc(),但这同样是个不确定的方法。Java 中并不保证每次调用该方法就一定能够启动垃圾收集,它只不过会向JVM发出这样一个申请,到底是否真正执行垃圾收集,一切都是个未知数。 (3)挑选适合自己的垃圾收集器。一般来说,如果系统没有特殊和苛刻的性能要求,可以采用JVM的缺省选项。否则可以考虑使用有针对性的垃圾收集器,比如增量收集器就比较适合实时性要求较高的系统之中。系统具有较高的配置,有比较多的闲置资源,可以考虑使用并行标记/清除收集器。 (4)关键的也是难把握的问题是内存泄漏。良好的编程习惯和严谨的编程态度永远是最重要的,不要让自己的一个小错误导致内存出现大漏洞。 (5)尽早释放无用对象的引用。大多数程序员在使用临时变量的时候,都是让引用变量在退出活动域(scope)后,自动设置为null,暗示垃圾收集器来收集该对象,还必须注意该引用的对象是否被监听,如果有,则要去掉监听器,然后再赋空值。就是说,对于频繁申请内存和释放内存的操作,还是自己控制一下比较好,但是System.gc()的方法不一定适用,最好使用finallize强制执行或者写自己的finallize方法。
System.gc()Runtime.gc()
垃圾回收不需要手工去做,java编译器已经默认提供了自动垃圾回收的方法

java垃圾回收常用的两种方法是什么

3,java中的垃圾回收机制是怎样的

比如你new了一个A类 用了一次之后不需要再用了。可以调用gc方法(垃圾回收的方法,这个懂了你就懂垃圾回收是干嘛的了)进行回收。 jvm自己知道把虚拟机中没用别调用的但是存在的实例回收。网上的资料( GC(Games Convention) 或 GC(Garbage Collection)  JAVA/.NET中的垃圾收集器。Java是由C++发展来的。它摈弃了C++中一些繁琐容易出错的东西。其中有一条就是这个GC。而C#又借鉴了JAVA。  在老式的C/C++程序中,程序员定义了一个变量,就是在内存中开辟了一段相应的空间来存值。由于内存是有限的,所以当程序不再需要使用某个变量的时候,就需要销毁该对象并释放其所占用的内存资源,好重新利用这段空间。在C/C++中,释放无用变量内存空间的事情需要由程序员自己来处理。就是说当程序员认为变量没用了,就手动地释放其占用的内存。但是这样显然非常繁琐,如果有所遗漏,就可能造成资源浪费甚至内存泄露。当软件系统比较复杂,变量多的时候程序员往往就忘记释放内存或者在不该释放的时候释放内存了。  有了GC,程序员就不需要再手动的去控制内存的释放。当Java虚拟机(VM)或.NET CLI发觉内存资源紧张的时候,就会自动地去清理无用对象(没有被引用到的对象)所占用的内存空间(这里的说法略显粗略,事实上何时清理内存是个复杂的策略)。如果需要,可以在程序中显式地使用System.gc() / System.GC.Collect()来强制进行一次立即的内存清理。)
1. gc的工作原理: 引用计数,标记复制"引用计数"是一种简单但速度很慢的垃圾回收技术.所有对象都有一个引用计数器,当有引用连接时计数器加1,当引用离开作用域时或者被置于null时,计数器-1,垃圾回收器会在所有包含对象引用的列表上进行遍历,当发现某个对象的引用计数为0时,就释放占用的空间."标记复制"的运行机制,垃圾回收器遍历包含所有引用的列表,当发现存活的对象引用时做上标记,这样当遍历完所有对象引用并做上标记的时候,执行垃圾回收,将没有标记的对象堆空间释放.2. 垃圾回收机制的优点:java的垃圾回收机制使得java程序员不用担心内存空间的分配,减少了内存溢出.但同时也牺牲了一定的性能.
Java的堆是一个运行时数据区,类的实例(对象)从中分配空间。Java虚拟机(JVM)的堆中储存着正在运行的应用程序所建立的所有对象,这些对象通过new、newarray、anewarray和multianewarray等指令建立,但是它们不需要程序代码来显式地释放。 一般来说,堆的是由垃圾回收 来负责的,尽管JVM规范并不要求特殊的垃圾回收技术,甚至根本就不需要垃圾回收,但是由于内存的有限性,JVM在实现的时候都有一个由垃圾回收所管理的堆。垃圾回收是一种动态存储管理技术,它自动地释放不再被程序引用的对象,按照特定的垃圾收集算法来实现资源自动回收的功能。
java 的垃圾回收机制:1.垃圾回收是由虚拟机自动执行,不能人为地干预。2.系统比较空闲(垃圾回收线程)3.对象不在被引用.对象处于引用的隔离岛状态(隔离引用),对象具备了回收的条件4.gc()方法,可以建议虚拟机执行垃圾回收,但是不能确定是否会执行回收。

java中的垃圾回收机制是怎样的

4,jvm垃圾回收有哪些算法

1.堆的分代和区域 (年轻代)Young Generation(eden、s0、s1 space) Minor GC (老年代)Old Generation (Tenured space) Major GC|| Full GC (永久代)Permanent Generation (Permanent space)【方法区(method area)】 Major GC 本地化的String从JDK 7开始就被移除了永久代(Permanent Generation ) JDK 8.HotSpot JVM开始使用本地化的内存存放类的元数据,这个空间叫做元空间(Metaspace)2.判断对象是否存活(哪些是垃圾对象) 1.引用计数(ReferenceCounting):对象有引用计数属性,增加一个引用计数加1,减少一个引用计数减1,计数为0时可回收。(无法解决对象相互循环引用的问题) 2.根搜索(GC Roots Tracing):GCRoot对象作为起始点(根)。如果从根到某个对象是可达的,则该对象称为“可达对象”(存活对象,不可回收对象)。否则就是不可达对象,可以被回收。 下图中,对象Object6、Object7、Object8虽然互相引用,但他们的GC Roots是不可到达的,所以它们将会被判定为是可回收的对象3.垃圾收集算法 1.标记-清除(Mark-Sweep)算法: 标记清除算法分为“标记”和“清除”两个阶段:首先标记出需要回收的对象,标记完成之后统一清除对象。 缺点: 1、标记和清除效率不高; 2、产生大量不连续的内存碎片,导致有大量内存剩余的情况下,由于,没有连续的空间来存放较大的对象,从而触发了另一次垃圾收集动作。2.复制(Copying)算法: 将可用内存容量划分为大小相等的两块,每次只使用其中的一块。当这一块用完之后,就将还存活的对象复制到另外一块上面,然后在把已使用过的内存空间一次清理掉。这样使得每次都是对其中的一块进行内存回收
1.垃圾回收目的:java语言中一个显著的特点就是引入了垃圾回收机制,使c++程序员最头疼的内存管理的问题迎刃而解,它使得java程序员在编写程序的时候不再需要考虑内存管理。由于有个垃圾回收机制,java中的对象不再有“作用域”的概念,只有对象的引用才有“作用域”。垃圾回收可以有效的防止内存泄露,有效的使用空闲的内存。ps:内存泄露是指该内存空间使用完毕之后未回收,在不涉及复杂数据结构的一般情况下,java 的内存泄露表现为一个内存对象的生命周期超出了程序需要它的时间长度,我们有时也将其称为“对象游离”。2.由于对象进行了分代处理,因此垃圾回收区域、时间也不一样。gc有两种类型:scavenge gc和full gc。scavenge gc一般情况下,当新对象生成,并且在eden申请空间失败时,就会触发scavenge gc,对eden区域进行gc,清除非存活对象,并且把尚且存活的对象移动到survivor区。然后整理survivor的两个区。这种方式的gc是对年轻代的eden区进行,不会影响到年老代。因为大部分对象都是从eden区开始的,同时eden区不会分配的很大,所以eden区的gc会频繁进行。因而,一般在这里需要使用速度快、效率高的算法,使eden去能尽快空闲出来。full gc对整个堆进行整理,包括young、tenured和perm。full gc因为需要对整个堆进行回收,所以比scavenge gc要慢,因此应该尽可能减少full gc的次数。在对jvm调优的过程中,很大一部分工作就是对于fullgc的调节。有如下原因可能导致full gc:1.年老代(tenured)被写满2.持久代(perm)被写满3.system.gc()被显示调用4.上一次gc之后heap的各域分配策略动态变化

5,java有哪些垃圾回收算法

常用的垃圾回收算法有:(1).引用计数算法:给对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加1;当引用失效时,计数器值就减1;任何时刻计数器都为0的对象就是不再被使用的,垃圾收集器将回收该对象使用的内存。引用计数算法实现简单,效率很高,微软的COM技术、ActionScript、Python等都使用了引用计数算法进行内存管理,但是引用计数算法对于对象之间相互循环引用问题难以解决,因此java并没有使用引用计数算法。(2).根搜索算法:通过一系列的名为“GC Root”的对象作为起点,从这些节点向下搜索,搜索所走过的路径称为引用链(Reference Chain),当一个对象到GC Root没有任何引用链相连时,则该对象不可达,该对象是不可使用的,垃圾收集器将回收其所占的内存。主流的商用程序语言C#、java和Lisp都使用根搜素算法进行内存管理。在java语言中,可作为GC Root的对象包括以下几种对象:a. java虚拟机栈(栈帧中的本地变量表)中的引用的对象。b.方法区中的类静态属性引用的对象。c.方法区中的常量引用的对象。d.本地方法栈中JNI本地方法的引用对象。java方法区在Sun HotSpot虚拟机中被称为永久代,很多人认为该部分的内存是不用回收的,java虚拟机规范也没有对该部分内存的垃圾收集做规定,但是方法区中的废弃常量和无用的类还是需要回收以保证永久代不会发生内存溢出。判断废弃常量的方法:如果常量池中的某个常量没有被任何引用所引用,则该常量是废弃常量。判断无用的类:(1).该类的所有实例都已经被回收,即java堆中不存在该类的实例对象。(2).加载该类的类加载器已经被回收。(3).该类所对应的java.lang.Class对象没有任何地方被引用,无法在任何地方通过反射机制访问该类的方法。Java中常用的垃圾收集算法:(1).标记-清除算法:最基础的垃圾收集算法,算法分为“标记”和“清除”两个阶段:首先标记出所有需要回收的对象,在标记完成之后统一回收掉所有被标记的对象。标记-清除算法的缺点有两个:首先,效率问题,标记和清除效率都不高。其次,标记清除之后会产生大量的不连续的内存碎片,空间碎片太多会导致当程序需要为较大对象分配内存时无法找到足够的连续内存而不得不提前触发另一次垃圾收集动作。(2).复制算法:将可用内存按容量分成大小相等的两块,每次只使用其中一块,当这块内存使用完了,就将还存活的对象复制到另一块内存上去,然后把使用过的内存空间一次清理掉。这样使得每次都是对其中一块内存进行回收,内存分配时不用考虑内存碎片等复杂情况,只需要移动堆顶指针,按顺序分配内存即可,实现简单,运行高效。复制算法的缺点显而易见,可使用的内存降为原来一半。(3).标记-整理算法:标记-整理算法在标记-清除算法基础上做了改进,标记阶段是相同的标记出所有需要回收的对象,在标记完成之后不是直接对可回收对象进行清理,而是让所有存活的对象都向一端移动,在移动过程中清理掉可回收的对象,这个过程叫做整理。标记-整理算法相比标记-清除算法的优点是内存被整理以后不会产生大量不连续内存碎片问题。复制算法在对象存活率高的情况下就要执行较多的复制操作,效率将会变低,而在对象存活率高的情况下使用标记-整理算法效率会大大提高。(4).分代收集算法:根据内存中对象的存活周期不同,将内存划分为几块,java的虚拟机中一般把内存划分为新生代和年老代,当新创建对象时一般在新生代中分配内存空间,当新生代垃圾收集器回收几次之后仍然存活的对象会被移动到年老代内存中,当大对象在新生代中无法找到足够的连续内存时也直接在年老代中创建。
System.gc是专门回收不用的对象的语法,当然你也可以自己写函数来finalization()你的程序。一般JVM会根据虚拟内存占用率来自动调用gc(garbage collector),有时候即便你调用gc如果内存占用不多回收处理工作也不会调用的,毕竟调用一次也要占用资源。
java垃圾回收直接用system.gc()就可以了。回收之前会调用复写的finalize()方法。没有必要去深入研究,实际开发中几乎不用,面试题中会出现,谢谢采纳。class person int num; string name; public person(string name,int num) this.name = name; this.num = num; } public string tostring() return "我是"+this.name+"编号:"+this.num; } @override public void finalize() throws throwable // todo auto-generated method stub system.out.println("我被回收了"+this); //这个this就代表了tostring对象本身。 } }public class systemfinalizetest public static void main(string[] args) // todo auto-generated method stub person p = new person("张三",10); p = null; system.gc(); }}

6,java垃圾是怎么回收的回收算法

Java ,C#语言与C/C++语言一个很大的区别是java与C#具有自动垃圾回收机制。C++程序员经常需要绞尽脑汁的分析哪里出现了内存泄漏。而在java,C#中,虽然有时也会出现内存泄漏,但大部分情况下程序员不需要考虑对象或者数据何时需要被销毁。因此程序员不会因为错误的释放内存而导致程序崩溃。垃圾回收的缺点是加大了程序的负担,有可能影响程序的性能。1.垃圾收集器的主要功能有(1) 定期发现那些对象不再被引用,并把这些对象占据的堆空间释放出来。(2) 类似于操作系统的内存管理,垃圾收集器还需要处理由于对象动态生成与销毁产生的堆碎块,以便更有效的利用虚拟机内存。2.区分活动对象与垃圾的算法(1)引用计数法堆中每一个对象都有一个引用计数。当新创建一个对象,或者有变量被赋值为这个对象的引用,则这个对象的引用计数加1;当一个对象的引用超过生存期或者被设置一个新的值时,这个对象的引用计数减1。当对象的引用计数变为0时,就可以被当作垃圾收集。这种方法的好处是垃圾收集较快,适用于实时环境。缺点是这种方法无法监测出循环引用。例如对象A引用对象B,对象B也引用对象A,则这两个对象可能无法被垃圾收集器收集。因此这种方法是垃圾收集的早期策略,现在很少使用。(2)跟踪法这种方法把每个对象看作图中一个节点,对象之间的引用关系为图中各节点的邻接关系。垃圾收集器从一个或数个根结点遍历对象图,如果有些对象节点永远无法到达,则这个对象可以被当作垃圾回收。容易发现,这种方法可以检测出循环引用,避免了引用计数法的缺点,较为常用。3.常用垃圾回收机制(1)标记-清除收集器这种收集器首先遍历对象图并标记可到达的对象,然后扫描堆栈以寻找未标记对象并释放它们的内存。这种收集器一般使用单线程工作并停止其他操作。(2)标记-压缩收集器有时也叫标记-清除-压缩收集器,与标记-清除收集器有相同的标记阶段。在第二阶段,则把标记对象复制到堆栈的新域中以便压缩堆栈。这种收集器也停止其他操作。(3)复制收集器这种收集器将堆栈分为两个域,常称为半空间。每次仅使用一半的空间,虚拟机生成的新对象则放在另一半空间中。垃圾回收器运行时,它把可到达对象复制到另一半空间,没有被复制的的对象都是不可达对象,可以被回收。这种方法适用于短生存期的对象,持续复制长生存期的对象由于多次拷贝,导致效率降低。缺点是只有一半的虚拟机空间得到使用。(4)增量收集器增量收集器把堆栈分为多个域,每次仅从一个域收集垃圾。这会造成较小的应用程序中断。(5)分代收集器这种收集器把堆栈分为两个或多个域,用以存放不同寿命的对象。虚拟机生成的新对象一般放在其中的某个域中。过一段时间,继续存在的对象将获得使用期并转入更长寿命的域中。分代收集器对不同的域使用不同的算法以优化性能。这样可以减少复制对象的时间。(6)并发收集器并发收集器与应用程序同时运行。这些收集器在某点上(比如压缩时)一般都不得不停止其他操作以完成特定的任务,但是因为其他应用程序可进行其他的后台操作,所以中断其他处理的实际时间大大降低。(7)并行收集器并行收集器使用某种传统的算法并使用多线程并行的执行它们的工作。在多CPU机器上使用多线程技术可以显著的提高java应用程序的可扩展性。(8)自适应收集器根据程序运行状况以及堆的使用状况,自动选一种合适的垃圾回收算法。这样可以不局限与一种垃圾回收算法。4. 火车算法垃圾收集算法一个很大的缺点就是难以控制垃圾回收所占用的CPU时间,以及何时需要进行垃圾回收。火车算法是分代收集器所用的算法,目的是在成熟对象空间中提供限定时间的渐进收集。目前应用于SUN公司的Hotspot虚拟机上。在火车算法中,内存被分为块,多个块组成一个集合。为了形象化,一节车厢代表一个块,一列火车代表一个集合,见图一注意每个车厢大小相等,但每个火车包含的车厢数不一定相等。垃圾收集以车厢为单位,收集顺序依次为1.1,1.2,1.3,1.4,2.1,2.2,2.3,3.1,3.2,3.3。这个顺序也是块被创建的先后顺序。垃圾收集器先从块1.1开始扫描直到1.4,如果火车1四个块中的所有对象没有被火车2和火车3的对象引用,而只有火车1内部的对象相互引用,则整个火车1都是垃圾,可以被回收。如图二,车厢1.1中有对象A和对象B,1.3中有对象C,1.4中有对象D,车厢2.2中有对象E,车厢3.3中有对象F。在火车1中,对象C引用对象A,对象B引用对象D,可见,火车2和火车3没有引用火车1的对象,则整个火车1都是垃圾。如果火车1中有对象被其它火车引用,见图三,扫描车厢1.1时发现对象A被火车2中的E引用,则将对象A从车厢1.1转移到车厢2.2,然后扫描A引用的对象D,把D也转移到车厢2.2,然后扫描D,看D是否引用其它对象,如果引用了其它对象则也要转移,依次类推。扫描完火车1的所有对象后,剩下的没有转移的对象都是垃圾,可以把整个火车1都作为垃圾回收。注意如果在转移时,如果车厢2.2空间满了,则要在火车2末尾开辟新的车厢2.4,将新转移的对象都放到2.4,即火车的尾部)补充说明:垃圾回收器一次只扫描一个车厢。图三中的对象B与C并不是立即被回收,而是先会被转移到火车1的尾部车厢。即扫描完1.1后,B被转移到火车1尾部,扫描完1.3后,C被转移到车尾。等垃圾收集器扫描到火车1尾部时,如果仍然没有外部对象引用它们,则B和C会被收集。火车算法最大的好处是它可以保证大的循环结构可以被完全收集,因为成为垃圾的循环结构中的对象,无论多大,都会被移入同一列火车,最终一起被收集。还有一个好处是这种算法在大多数情况下可以保证一次垃圾收集所耗时间在一定限度之内,因为一次垃圾回收只收集一个车厢,而车厢的大小是有限度的。
算法。。。。。。。。。。。。。。。
1.Serial New/Serial Old Serial/Serial Old收集器是最基本最古老的收集器,它是一个单线程收集器,并且在它进行垃圾收集时,必须暂停所有用户线程。Serial New收集器是针对新生代的收集器,采用的是Copying算法,Serial Old收集器是针对老年代的收集器,采用的是Mark-Compact算法。它的优点是实现简单高效,但是缺点是会给用户带来停顿。2.Parallel New Parallel New收集器是Serial收集器的多线程版本(参照Serial New),使用多个线程进行垃圾收集。3.Parallel Scavenge Parallel Scavenge收集器是一个新生代的多线程收集器(并行收集器),它在回收期间不需要暂停其他用户线程,其采用的是Copying算法,该收集器与前两个收集器有所不同,它主要是为了达到一个可控的吞吐量。4.Parallel Old Parallel Old是Parallel Scavenge收集器的老年代版本(并行收集器),使用多线程和Mark-Compact算法。5.CMS CMS(Current Mark Sweep)收集器是一种以获取最短回收停顿时间为目标的收集器,它是一种并发收集器,采用的是Mark-Sweep算法。6.G1 G1收集器是当今收集器技术发展最前沿的成果,它是一款面向服务端应用的收集器,它能充分利用多CPU、多核环境。因此它是一款并行与并发收集器,并且它能建立可预测的停顿时间模型。

文章TAG:java  垃圾  垃圾回收  回收  java垃圾回收算法  
下一篇