⑴ java的垃圾回收机制是什么 请详细解释
Java的垃圾回收机制是Java虚拟机提供的能力,用于在空闲时间以不定时的方式动态回收无任何引用的对象占据的内存空间。
⑵ java的垃圾回收机制是什么
1、回收的内容是new出来的对象所占内存;
2、垃圾回收只与内存有关,清理内存外的资源依靠finalize()方法。垃圾回收机制在回收某个对象的内存前会调用该对象的finalize()方法。
3、强制系统垃圾回收的方式(通过程序通知系统进行垃圾回收,但系统还不一定进行垃圾回收):
System.gc();
Runtime.getRuntime().gc();
5、对象在内存中的状态有可达状态、可恢复状态、不可达状态,当处于可恢复状态时可能会进行垃圾回收。
⑶ java中是怎样进行垃圾回收的
前面是我自己理解的后面是复制的
java中垃圾回收以前听老师讲好像是内存满了他才去做一次整体垃圾回收,在回收垃圾的同时会调用finalize方法.你在构造一个类时可以构造一个类时覆盖他的finalize方法以便于该类在被垃圾回收时执行一些代码,比如释放资源.
1.JVM的gc概述
gc即垃圾收集机制是指jvm用于释放那些不再使用的对象所占用的内存。java语言并不要求jvm有gc,也没有规定gc如何工作。不过常用的jvm都有gc,而且大多数gc都使用类似的算法管理内存和执行收集操作。
在充分理解了垃圾收集算法和执行过程后,才能有效的优化它的性能。有些垃圾收集专用于特殊的应用程序。比如,实时应用程序主要是为了避免垃圾收集中断,而大多数OLTP应用程序则注重整体效率。理解了应用程序的工作负荷和jvm支持的垃圾收集算法,便可以进行优化配置垃圾收集器。
垃圾收集的目的在于清除不再使用的对象。gc通过确定对象是否被活动对象引用来确定是否收集该对象。gc首先要判断该对象是否是时候可以收集。两种常用的方法是引用计数和对象引用遍历。
1.1.引用计数
引用计数存储对特定对象的所有引用数,也就是说,当应用程序创建引用以及引用超出范围时,jvm必须适当增减引用数。当某对象的引用数为0时,便可以进行垃圾收集。
1.2.对象引用遍历
早期的jvm使用引用计数,现在大多数jvm采用对象引用遍历。对象引用遍历从一组对象开始,沿着整个对象图上的每条链接,递归确定可到达(reachable)的对象。如果某对象不能从这些根对象的一个(至少一个)到达,则将它作为垃圾收集。在对象遍历阶段,gc必须记住哪些对象可以到达,以便删除不可到达的对象,这称为标记(marking)对象。
下一步,gc要删除不可到达的对象。删除时,有些gc只是简单的扫描堆栈,删除未标记的未标记的对象,并释放它们的内存以生成新的对象,这叫做清除(sweeping)。这种方法的问题在于内存会分成好多小段,而它们不足以用于新的对象,但是组合起来却很大。因此,许多gc可以重新组织内存中的对象,并进行压缩(compact),形成可利用的空间。
为此,gc需要停止其他的活动活动。这种方法意味着所有与应用程序相关的工作停止,只有gc运行。结果,在响应期间增减了许多混杂请求。另外,更复杂的 gc不断增加或同时运行以减少或者清除应用程序的中断。有的gc使用单线程完成这项工作,有的则采用多线程以增加效率。
2.几种垃圾回收机制
2.1.标记-清除收集器
这种收集器首先遍历对象图并标记可到达的对象,然后扫描堆栈以寻找未标记对象并释放它们的内存。这种收集器一般使用单线程工作并停止其他操作。
2.2.标记-压缩收集器
有时也叫标记-清除-压缩收集器,与标记-清除收集器有相同的标记阶段。在第二阶段,则把标记对象复制到堆栈的新域中以便压缩堆栈。这种收集器也停止其他操作。
2.3.复制收集器
这种收集器将堆栈分为两个域,常称为半空间。每次仅使用一半的空间,jvm生成的新对象则放在另一半空间中。gc运行时,它把可到达对象复制到另一半空间,从而压缩了堆栈。这种方法适用于短生存期的对象,持续复制长生存期的对象则导致效率降低。
2.4.增量收集器
增量收集器把堆栈分为多个域,每次仅从一个域收集垃圾。这会造成较小的应用程序中断。
2.5.分代收集器
这种收集器把堆栈分为两个或多个域,用以存放不同寿命的对象。jvm生成的新对象一般放在其中的某个域中。过一段时间,继续存在的对象将获得使用期并转入更长寿命的域中。分代收集器对不同的域使用不同的算法以优化性能。
2.6.并发收集器
并发收集器与应用程序同时运行。这些收集器在某点上(比如压缩时)一般都不得不停止其他操作以完成特定的任务,但是因为其他应用程序可进行其他的后台操作,所以中断其他处理的实际时间大大降低。
2.7.并行收集器
并行收集器使用某种传统的算法并使用多线程并行的执行它们的工作。在多cpu机器上使用多线程技术可以显着的提高java应用程序的可扩展性。
3.Sun HotSpot
1.4.1 JVM堆大小的调整
Sun HotSpot 1.4.1使用分代收集器,它把堆分为三个主要的域:新域、旧域以及永久域。Jvm生成的所有新对象放在新域中。一旦对象经历了一定数量的垃圾收集循环后,便获得使用期并进入旧域。在永久域中jvm则存储class和method对象。就配置而言,永久域是一个独立域并且不认为是堆的一部分。
下面介绍如何控制这些域的大小。可使用-Xms和-Xmx 控制整个堆的原始大小或最大值。
下面的命令是把初始大小设置为128M:
java –Xms128m
–Xmx256m为控制新域的大小,可使用-XX:NewRatio设置新域在堆中所占的比例。
下面的命令把整个堆设置成128m,新域比率设置成3,即新域与旧域比例为1:3,新域为堆的1/4或32M:
java –Xms128m –Xmx128m
–XX:NewRatio =3可使用-XX:NewSize和-XX:MaxNewsize设置新域的初始值和最大值。
下面的命令把新域的初始值和最大值设置成64m:
java –Xms256m –Xmx256m –Xmn64m
永久域默认大小为4m。运行程序时,jvm会调整永久域的大小以满足需要。每次调整时,jvm会对堆进行一次完全的垃圾收集。
使用-XX:MaxPerSize标志来增加永久域搭大小。在WebLogic Server应用程序加载较多类时,经常需要增加永久域的最大值。当jvm加载类时,永久域中的对象急剧增加,从而使jvm不断调整永久域大小。为了避免调整,可使用-XX:PerSize标志设置初始值。
下面把永久域初始值设置成32m,最大值设置成64m。
java -Xms512m -Xmx512m -Xmn128m -XX:PermSize=32m -XX:MaxPermSize=64m
默认状态下,HotSpot在新域中使用复制收集器。该域一般分为三个部分。第一部分为Eden,用于生成新的对象。另两部分称为救助空间,当Eden 充满时,收集器停止应用程序,把所有可到达对象复制到当前的from救助空间,一旦当前的from救助空间充满,收集器则把可到达对象复制到当前的to救助空间。From和to救助空间互换角色。维持活动的对象将在救助空间不断复制,直到它们获得使用期并转入旧域。使用-XX:SurvivorRatio 可控制新域子空间的大小。
同NewRation一样,SurvivorRation规定某救助域与Eden空间的比值。比如,以下命令把新域设置成64m,Eden占32m,每个救助域各占16m:
java -Xms256m -Xmx256m -Xmn64m -XX:SurvivorRation =2
如前所述,默认状态下HotSpot对新域使用复制收集器,对旧域使用标记-清除-压缩收集器。在新域中使用复制收集器有很多意义,因为应用程序生成的大部分对象是短寿命的。理想状态下,所有过渡对象在移出Eden空间时将被收集。如果能够这样的话,并且移出Eden空间的对象是长寿命的,那么理论上可以立即把它们移进旧域,避免在救助空间反复复制。但是,应用程序不能适合这种理想状态,因为它们有一小部分中长寿命的对象。最好是保持这些中长寿命的对象并放在新域中,因为复制小部分的对象总比压缩旧域廉价。为控制新域中对象的复制,可用-XX:TargetSurvivorRatio控制救助空间的比例(该值是设置救助空间的使用比例。如救助空间位1M,该值50表示可用500K)。该值是一个百分比,默认值是50。当较大的堆栈使用较低的 sruvivorratio时,应增加该值到80至90,以更好利用救助空间。用-XX:maxtenuring threshold可控制上限。
为放置所有的复制全部发生以及希望对象从eden扩展到旧域,可以把MaxTenuring Threshold设置成0。设置完成后,实际上就不再使用救助空间了,因此应把SurvivorRatio设成最大值以最大化Eden空间,设置如下:
java … -XX:MaxTenuringThreshold=0 –XX:SurvivorRatio=50000 …
4.BEA JRockit JVM的使用
Bea WebLogic 8.1使用的新的JVM用于Intel平台。在Bea安装完毕的目录下可以看到有一个类似于jrockit81sp1_141_03的文件夹。这就是 Bea新JVM所在目录。不同于HotSpot把Java字节码编译成本地码,它预先编译成类。JRockit还提供了更细致的功能用以观察JVM的运行状态,主要是独立的GUI控制台(只能适用于使用Jrockit才能使用jrockit81sp1_141_03自带的console监控一些cpu及 memory参数)或者WebLogic Server控制台。
Bea JRockit JVM支持4种垃圾收集器:
4.1.1.分代复制收集器
它与默认的分代收集器工作策略类似。对象在新域中分配,即JRockit文档中的nursery。这种收集器最适合单cpu机上小型堆操作。
4.1.2.单空间并发收集器
该收集器使用完整堆,并与背景线程共同工作。尽管这种收集器可以消除中断,但是收集器需花费较长的时间寻找死对象,而且处理应用程序时收集器经常运行。如果处理器不能应付应用程序产生的垃圾,它会中断应用程序并关闭收集。
分代并发收集器这种收集器在护理域使用排它复制收集器,在旧域中则使用并发收集器。由于它比单空间共同发生收集器中断频繁,因此它需要较少的内存,应用程序的运行效率也较高,注意,过小的护理域可以导致大量的临时对象被扩展到旧域中。这会造成收集器超负荷运作,甚至采用排它性工作方式完成收集。
4.1.3.并行收集器
该收集器也停止其他进程的工作,但使用多线程以加速收集进程。尽管它比其他的收集器易于引起长时间的中断,但一般能更好的利用内存,程序效率也较高。
默认状态下,JRockit使用分代并发收集器。要改变收集器,可使用-Xgc:,对应四个收集器分别为 gen,singlecon,gencon以及parallel。可使用-Xms和-Xmx设置堆的初始大小和最大值。要设置护理域,则使用- Xns:java –jrockit –Xms512m –Xmx512m –Xgc:gencon –Xns128m…尽管JRockit支持-verbose:gc开关,但它输出的信息会因收集器的不同而异。JRockit还支持memory、 load和codegen的输出。
注意 :如果 使用JRockit JVM的话还可以使用WLS自带的console(C:\bea\jrockit81sp1_141_03\bin下)来监控一些数据,如cpu, memery等。要想能构监控必须在启动服务时startWeblogic.cmd中加入-Xmanagement参数。
5.如何从JVM中获取信息来进行调整
-verbose.gc开关可显示gc的操作内容。打开它,可以显示最忙和最空闲收集行为发生的时间、收集前后的内存大小、收集需要的时间等。打开- xx:+ printgcdetails开关,可以详细了解gc中的变化。打开-XX: + PrintGCTimeStamps开关,可以了解这些垃圾收集发生的时间,自jvm启动以后以秒计量。最后,通过-xx: + PrintHeapAtGC开关了解堆的更详细的信息。为了了解新域的情况,可以通过-XX:=PrintTenuringDistribution开关了解获得使用期的对象权。
6.Pdm系统JVM调整
6.1.服务器:前提内存1G 单CPU
可通过如下参数进行调整:-server 启用服务器模式(如果CPU多,服务器机建议使用此项)
-Xms,-Xmx一般设为同样大小。 800m
-Xmn 是将NewSize与MaxNewSize设为一致。320m
-XX:PerSize 64m
-XX:NewSize 320m 此值设大可调大新对象区,减少Full GC次数
-XX:MaxNewSize 320m
-XX:NewRato NewSize设了可不设。
-XX: SurvivorRatio
-XX:userParNewGC 可用来设置并行收集
-XX:ParallelGCThreads 可用来增加并行度
-XXUseParallelGC 设置后可以使用并行清除收集器
-XX:UseAdaptiveSizePolicy 与上面一个联合使用效果更好,利用它可以自动优化新域大小以及救助空间比值
6.2.客户机:通过在JNLP文件中设置参数来调整客户端JVM
JNLP中参数:initial-heap-size和max-heap-size
这可以在framework的RequestManager中生成JNLP文件时加入上述参数,但是这些值是要求根据客户机的硬件状态变化的(如客户机的内存大小等)。建议这两个参数值设为客户机可用内存的60%(有待测试)。为了在动态生成JNLP时以上两个参数值能够随客户机不同而不同,可靠虑获得客户机系统信息并将这些嵌到首页index.jsp中作为连接请求的参数。
在设置了上述参数后可以通过Visualgc 来观察垃圾回收的一些参数状态,再做相应的调整来改善性能。一般的标准是减少fullgc的次数,最好硬件支持使用并行垃圾回收(要求多CPU)。
⑷ java中垃圾回收有哪几种机制
强引用
在一般的Java程序中,见到最多的就是强引用(strong reference)。如Date date = new Date(),date就是一个对象的强引用。对象的强引用可以在程序中到处传递。很多情况下,会同时有多个引用指向同一个对象。强引用的存在限制了对象在内存中的存活时间。假如对象A中包含了一个对象B的强引用,那么一般情况下,对象B的存活时间就不会短于对象A。如果对象A没有显式的把对象B的引用设为null的话,就只有当对象A被垃圾回收之后,对象B才不再有引用指向它,才可能获得被垃圾回收的机会。
除了强引用之外,java.lang.ref包中提供了对一个对象的不同的引用方式。JVM的垃圾回收器对于不同类型的引用有不同的处理方式。
软引用
软引用(soft reference)在强度上弱于强引用,通过类SoftReference来表示。它的作用是告诉垃圾回收器,程序中的哪些对象是不那么重要,当内存不足的时候是可以被暂时回收的。当JVM中的内存不足的时候,垃圾回收器会释放那些只被软引用所指向的对象。如果全部释放完这些对象之后,内存还不足,才会抛出OutOfMemory错误。软引用非常适合于创建缓存。当系统内存不足的时候,缓存中的内容是可以被释放的。比如考虑一个图像编辑器的程序。该程序会把图像文件的全部内容都读取到内存中,以方便进行处理。而用户也可以同时打开多个文件。当同时打开的文件过多的时候,就可能造成内存不足。如果使用软引用来指向图像文件内容的话,垃圾回收器就可以在必要的时候回收掉这些内存。
publicclass ImageData {
private String path;
private SoftReference<byte[]> dataRef;
public ImageData(String path) {
this.path = path;
dataRef = new SoftReference<byte[]>(newbyte[0]);
}
privatebyte[] readImage() {
returnnewbyte[1024 * 1024]; //省略了读取文件的操作 }
publicbyte[] getData() {
byte[] dataArray = dataRef.get();
if (dataArray == null || dataArray.length == 0) {
dataArray = readImage();
dataRef = new SoftReference<byte[]>(dataArray);
}
return dataArray;
}
}
在运行上面程序的时候,可以使用 -Xmx 参数来限制JVM可用的内存。由于软引用所指向的对象可能被回收掉,在通过get方法来获取软引用所实际指向的对象的时候,总是要检查该对象是否还存活。
弱引用
弱引用(weak reference)在强度上弱于软引用,通过类WeakReference来表示。它的作用是引用一个对象,但是并不阻止该对象被回收。如果使用一个强引用的话,只要该引用存在,那么被引用的对象是不能被回收的。弱引用则没有这个问题。在垃圾回收器运行的时候,如果一个对象的所有引用都是弱引用的话,该对象会被回收。弱引用的作用在于解决强引用所带来的对象之间在存活时间上的耦合关系。弱引用最常见的用处是在集合类中,尤其在哈希表中。哈希表的接口允许使用任何Java对象作为键来使用。当一个键值对被放入到哈希表中之后,哈希表对象本身就有了对这些键和值对象的引用。如果这种引用是强引用的话,那么只要哈希表对象本身还存活,其中所包含的键和值对象是不会被回收的。如果某个存活时间很长的哈希表中包含的键值对很多,最终就有可能消耗掉JVM中全部的内存。
对于这种情况的解决办法就是使用弱引用来引用这些对象,这样哈希表中的键和值对象都能被垃圾回收。Java中提供了WeakHashMap来满足这一常见需求。
幽灵引用
在介绍幽灵引用之前,要先介绍Java提供的对象终止化机制(finalization)。在Object类里面有个finalize方法,其设计的初衷是在一个对象被真正回收之前,可以用来执行一些清理的工作。因为Java并没有提供类似C++的析构函数一样的机制,就通过 finalize方法来实现。但是问题在于垃圾回收器的运行时间是不固定的,所以这些清理工作的实际运行时间也是不能预知的。幽灵引用(phantom reference)可以解决这个问题。在创建幽灵引用PhantomReference的时候必须要指定一个引用队列。当一个对象的finalize方法已经被调用了之后,这个对象的幽灵引用会被加入到队列中。通过检查该队列里面的内容就知道一个对象是不是已经准备要被回收了。
幽灵引用及其队列的使用情况并不多见,主要用来实现比较精细的内存使用控制,这对于移动设备来说是很有意义的。程序可以在确定一个对象要被回收之后,再申请内存创建新的对象。通过这种方式可以使得程序所消耗的内存维持在一个相对较低的数量。
⑸ Java垃圾回收机制是什么
垃圾是指:无用的对象或者引用
回收:清除其所占内存
机制:自动发生或(gc())
⑹ Java中垃圾回收有什么目的什么时候进行垃圾回收
垃圾回收器的作用是查找和回收(清理)无用的对象。以便让JVM更有效的使用内存。
垃圾回收器的运行时间是不确定的,由JVM决定,在运行时是间歇执行的。虽然可以通过System.gc()来强制回收垃圾,但是这个命令下达后无法保证JVM会立即响应执行,但经验表明,下达命令后,会在短期内执行的请求。JVM通常会感到内存紧缺时候去执行垃圾回收操作。
垃圾回收过于频繁会导致性能下降,过于稀疏会导致内存紧缺。这个JVM会将其控制到最好,不用程序员担心。但有些程序在短期会吃掉大量内存,而这些恐怖的对象很快使用结束了,这时候也许有必要强制下达一条垃圾回命令,这是很有必要的,以便有更多可用的物理内存。
⑺ java中垃圾回收机制的原理
java中垃圾回收机制的原理
推荐一篇文章:
对高性能JAVA代码之内存管理
更甚者你写的代码,GC根本就回收不了,直接系统挂掉。GC是一段程序,不是智能,他只回收他认为的垃圾,而不是回收你认为的垃圾。
GC垃圾回收:
Grabage Collection相信学过JAVA的人都知道这个是什么意思。但是他是如何工作的呢?
首先,JVM在管理内存的时候对于变量的管理总是分新对象和老对象。新对象也就是开发者new出来的对象,但是由于生命周期短,那么他占用的内存并不是马上释放,而是被标记为老对象,这个时候该对象还是要存在一段时间。然后由JVM决定他是否是垃圾对象,并进行回收。
所以我们可以知道,垃圾内存并不是用完了马上就被释放,所以就会产生内存释放不及时的现象,从而降低了内存的使用。而当程序浩大的时候。这种现象更为明显,并且GC的工作也是需要消耗资源的。所以,也就会产生内存浪费。
JVM中的对象生命周期里谈内存回收:
对象的生命周期一般分为7个阶段:创建阶段,应用阶段,不可视阶段,不可到达阶段,可收集阶段,终结阶段,释放阶段。
创建阶段:首先大家看一下,如下两段代码:
test1:
for( int i=0; i《10000; i++)
Object obj=new Object();
test2:
Object obj=null;
for( int i=0; i《10000; i++)
obj=new Object();
这两段代码都是相同的功能,但是显然test2的性能要比test1性能要好,内存使用率要高,这是为什么呢?原因很简单,test1每次执行for循环都要创建一个Object的临时对象,但是这些临时对象由于JVM的GC不能马上销毁,所以他们还要存在很长时间,而test2则只是在内存中保存一份对象的引用,而不必创建大量新临时变量,从而降低了内存的使用。
另外不要对同一个对象初始化多次。例如:
public class A{
private Hashtable table = new Hashtable();
public A(){ table = new Hashtable();
// 这里应该去掉,因为table已经被初始化。
}
这样就new了两个Hashtable,但是却只使用了一个。另外一个则没有被引用。而被忽略掉。浪费了内存。并且由于进行了两次new操作。也影响了代码的执行速度。
应用阶段:即该对象至少有一个引用在维护他。
不可视阶段:即超出该变量的作用域。这里有一个很好的做法,因为JVM在GC的时候并不是马上进行回收,而是要判断对象是否被其他引用在维护。所以,这个时候如果我们在使用完一个对象以后对其obj=null或者obj.doSomething()操作,将其标记为空,可以帮助JVM及时发现这个垃圾对象。
不可到达阶段:就是在JVM中找不到对该对象的直接或者间接的引用。
可收集阶段,终结阶段,释放阶段:此为回收器发现该对象不可到达,finalize方法已经被执行,或者对象空间已被重用的时候。
JAVA的析构方法:
可能不会有人相信,JAVA有析构函数? 是的,有。因为JAVA所有类都继承至Object类,而finalize就是Object类的一个方法,这个方法在JAVA中就是类似于C++析构函数。一般来说可以通过重载finalize方法的形式才释放类中对象。如:
public class A{
public Object a;
public A(){ a = new Object ;}
protected void finalize() throws java.lang.Throwable{
a = null; // 标记为空,释放对象
super.finalize(); // 递归调用超类中的finalize方法。
}
}
当然,什么时候该方法被调用是由JVM来决定的。..。..。..。..。..。..。..。.
一般来说,我们需要创建一个destory的方法来显式的调用该方法。然后在finalize也对该方法进行调用,实现双保险的做法。
由于对象的创建是递归式的,也就是先调用超级类的构造,然后依次向下递归调用构造函数,所以应该避免在类的构造函数中初始化变量,这样可以避免不必要的创建对象造成不必要的内存消耗。当然这里也就看出来接口的优势。
数组的创建:
由于数组需要给定一个长度,所以在不确定数据数量的时候经常会创建过大,或过小的数组的现象。造成不必要的内存浪费,所以可以通过软引用的方式来告诉JVM及时回收该内存。(软引用,具体查资料)。
例如:
Object obj = new char[10000000000000000];
SoftReference ref = new SoftReference(obj);
共享静态存储空间:
我们都知道静态变量在程序运行期间其内存是共享的,因此有时候为了节约内存工件,将一些变量声明为静态变量确实可以起到节约内存空间的作用。但是由于静态变量生命周期很长,不易被系统回收,所以使用静态变量要合理,不能盲目的使用。以免适得其反。
因此建议在下面情况下使用:
1,变量所包含的对象体积较大,占用内存过多。
2,变量所包含对象生命周期较长。
3,变量所包含数据稳定。
4,该类的对象实例有对该变量所包含的对象的共享需求。(也就是说是否需要作为全局变量)。
对象重用与GC:
有的时候,如数据库操作对象,一般情况下我们都需要在各个不同模块间使用,所以这样的对象需要进行重用以提高性能。也有效的避免了反复创建对象引起的性能下降。
一般来说对象池是一个不错的注意。如下:
public abstarct class ObjectPool{
private Hashtable locked,unlocked;
private long expirationTime;
abstract Object create();
abstract void expire( Object o);
abstract void validate( Object o);
synchronized Object getObject(){。..};
synchronized void freeObject(Object o){。..};
这样我们就完成了一个对象池,我们可以将通过对应的方法来存取删除所需对象。来维护这快内存提高内存重用。
当然也可以通过调用System.gc()强制系统进行垃圾回收操作。当然这样的代价是需要消耗一些cpu资源。
不要提前创建对象:
尽量在需要的时候创建对象,重复的分配,构造对象可能会因为垃圾回收做额外的工作降低性能。
JVM内存参数调优:
强制内存回收对于系统自动的内存回收机制会产生负面影响,会加大系统自动回收的处理时间,所以应该尽量避免显式使用System.gc(),
JVM的设置可以提高系统的性能。例如:
java -XX:NewSize=128m -XX:MaxNewSize=128m -XX:SurvivorRatio=8 -Xms512m -Xmx512m
具体可以查看java帮助文档。我们主要介绍程序设计方面的性能提高。
JAVA程序设计中有关内存管理的其他经验:
根据JVM内存管理的工作原理,可以通过一些技巧和方式让JVM做GC处理时更加有效。,从而提高内存使用和缩短GC的执行时间。
1,尽早释放无用对象的引用。即在不使用对象的引用后设置为空,可以加速GC的工作。(当然如果是返回值。..。.)
2,尽量少用finalize函数,此函数是JAVA给程序员提供的一个释放对象或资源的机会,但是却会加大GC工作量。
3,如果需要使用到图片,可以使用soft应用类型,它可以尽可能将图片读入内存而不引起OutOfMemory.
4,注意集合数据类型的数据结构,往往数据结构越复杂,GC工作量更大,处理更复杂。
5,尽量避免在默认构造器(构造函数)中创建,初始化大量的对象。
6,尽量避免强制系统做垃圾回收。会增加系统做垃圾回收的最终时间降低性能。
7,尽量避免显式申请数组,如果不得不申请数组的话,要尽量准确估算数组大小。
8,如果在做远程方法调用。要尽量减少传递的对象大小。或者使用瞬间值避免不必要数据的传递。
9,尽量在合适的情况下使用对象池来提高系统性能减少内存开销,当然,对象池不能过于庞大,会适得其反.
⑻ 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方法。
⑼ java垃圾回收是什么
垃圾回收叫做GC:garbage collection,是java虚拟机JVM提供的一种内存回收方式。开发者在使用java开发的时候不需要像使用C/C++一样去手动释放内存,虚拟机会通过自动检测的方式,去释放内存。比如你用java new了一个对象,这个时候你得到了一个强引用,strong reference。当你不在需要这个对象的时候,你只需要把它设置成null。这个时候JVM并不会立刻回收掉这块内存,在之后的某个时间点,当JVM检测内存的时候发现这块内存已经没有任何强引用了,就会把它释放掉。
⑽ java中的垃圾回收是什么意思
垃圾回收就是gc(gabage collection)。
java比c++的优点就是多了垃圾回收机制,程序员不用去关心垃圾的回收,系统会自动调用去回收内存。
一般我们想回收的时候只需要调用system.gc方法就可以了。系统会自己去调用destroy方法和其他的回收方法释放内存,节省内存空间。