如何让System.gc()更快的工作

最近在在翻看java的Garbage Collection,即大名鼎鼎的垃圾收集器GC的相关资料,整理了一下头绪,和朋友们共勉之。

Java的GC机制大名远扬,它大幅提高了程序员开发效率,省去了在c#中要显式的释放每一块内存的麻烦。我们常听到的“内存泄漏”实际上就是指无用的内存没有被及时回收。例如你声明了一个变量,而该变量所在的主进程需要运行很长时间,那么就形成了局部上的“内存泄漏”。“内存泄漏”是相对来说的,即在内存资源紧张的时候,无用的内存没有被回收,系统就会面临内存泄漏的危险。

那现在说下什么样的情况会被GC回收,说简单点就是通路断掉的内存会被回收。可以看下面例子:

  1. Objecto1=newObject();
  2. Objecto2=newObject();
  3. o2=o1;

o2=o1指明了这2个变量都指向了同一个对象,即使用了同一块内存区域,那么我们就说原o2申明的Object对象的那块内存会被GC回收,因为没有通路和它连通。

GC回收对程序员来说是透明的,要及时释放内存,最稳妥的方法就是在对象被使用完毕后,立即为该对象赋值为null,但是我们不知道什么时候这些无用资源会被回收,有什么办法可以显示执行吗?有的,就是显示调用System.gc();(该方法不保证立即会执行,因为不同的JVM使用不用算法来管理GC)。要让gc()达到立竿见影的效果,可以选择使用jdk1.2以来引入的4种对象引用类型上,废话不多说,看程序来说话:

  1. importjava.lang.ref.PhantomReference;
  2. importjava.lang.ref.ReferenceQueue;
  3. importjava.lang.ref.SoftReference;
  4. importjava.lang.ref.WeakReference;
  5. classMyObject{
  6. privateStringid;
  7. publicMyObject(Stringid){
  8. this.id=id;
  9. }
  10. publicStringtoString(){
  11. returnid;
  12. }
  13. publicvoidfinalize(){
  14. System.out.println("回收对象:"+id);
  15. }
  16. }
  17. publicclassTestReferences{
  18. publicstaticvoidmain(String[]args){
  19. //创建强引用
  20. MyObjectref=newMyObject("Hard");
  21. System.out.println(ref);
  22. ref=null;
  23. System.gc();
  24. System.out.println(ref);
  25. //创建软引用
  26. SoftReference<myobject></myobject>softRef=newSoftReference<myobject></myobject>(
  27. newMyObject("Soft"));
  28. System.out.println(softRef.get());
  29. System.gc();
  30. System.out.println(softRef.get());
  31. //创建弱引用
  32. WeakReference<myobject></myobject>weakRef=newWeakReference<myobject></myobject>(
  33. newMyObject("Weak"));
  34. System.out.println("beforegc——"+weakRef.get());
  35. System.gc();
  36. System.out.println("aftergc——"+weakRef.get());
  37. //创建虚引用
  38. ReferenceQueue<myobject></myobject>rq=newReferenceQueue<myobject></myobject>();
  39. PhantomReference<myobject></myobject>phantomRef=newPhantomReference<myobject></myobject>(
  40. newMyObject("Phantom"),rq);
  41. System.out.println("beforegc——"+phantomRef.get());
  42. System.gc();
  43. System.out.println("aftergc——"+phantomRef.get());
  44. }
  45. }

输出如下:

Hard
null
Soft
Soft
回收对象:Hard
before gc —— Weak
after gc —— null
回收对象:Weak
before gc —— null
after gc —— null
回收对象:Phantom

以上我们创建了4种引用,依次是:强引用、软引用、弱引用、虚引用。

强引用即我们普通使用的申明方式,对于该引用,只有显示的赋值为null,gc才会视为回收对象。

软引用(SoftReference)是只有内存不足时,gc才会将它视为回收对象。

弱引用(WeakReference)是无论当前内存是否满足,gc都会去回收它。

虚引用(PahntomReference)实际是可以理解成“子虚乌有”的引用,目的仅仅是结合引用关联队列(ReferenceQueue),实现对对象引用关系的跟踪。

在MyObject类中finalize方法中,我们让它在被回收时打印一句话出来,从输出结果来看,我们可以很容易的理解GC这4种对象引用的不同处理方式。从中我们可以得到结论,System.gc()可以对弱引用和虚引用达到立竿见影的效果。

好了以上一点小建议、想法,希望能对你有所帮助!

最近在在翻看java的Garbage Collection,即大名鼎鼎的垃圾收集器GC的相关资料,整理了一下头绪,和朋友们共勉之。

Java的GC机制大名远扬,它大幅提高了程序员开发效率,省去了在c#中要显式的释放每一块内存的麻烦。我们常听到的“内存泄漏”实际上就是指无用的内存没有被及时回收。例如你声明了一个变量,而该变量所在的主进程需要运行很长时间,那么就形成了局部上的“内存泄漏”。“内存泄漏”是相对来说的,即在内存资源紧张的时候,无用的内存没有被回收,系统就会面临内存泄漏的危险。

那现在说下什么样的情况会被GC回收,说简单点就是通路断掉的内存会被回收。可以看下面例子:

  1. Objecto1=newObject();
  2. Objecto2=newObject();
  3. o2=o1;

o2=o1指明了这2个变量都指向了同一个对象,即使用了同一块内存区域,那么我们就说原o2申明的Object对象的那块内存会被GC回收,因为没有通路和它连通。

GC回收对程序员来说是透明的,要及时释放内存,最稳妥的方法就是在对象被使用完毕后,立即为该对象赋值为null,但是我们不知道什么时候这些无用资源会被回收,有什么办法可以显示执行吗?有的,就是显示调用System.gc();(该方法不保证立即会执行,因为不同的JVM使用不用算法来管理GC)。要让gc()达到立竿见影的效果,可以选择使用jdk1.2以来引入的4种对象引用类型上,废话不多说,看程序来说话:

  1. importjava.lang.ref.PhantomReference;
  2. importjava.lang.ref.ReferenceQueue;
  3. importjava.lang.ref.SoftReference;
  4. importjava.lang.ref.WeakReference;
  5. classMyObject{
  6. privateStringid;
  7. publicMyObject(Stringid){
  8. this.id=id;
  9. }
  10. publicStringtoString(){
  11. returnid;
  12. }
  13. publicvoidfinalize(){
  14. System.out.println("回收对象:"+id);
  15. }
  16. }
  17. publicclassTestReferences{
  18. publicstaticvoidmain(String[]args){
  19. //创建强引用
  20. MyObjectref=newMyObject("Hard");
  21. System.out.println(ref);
  22. ref=null;
  23. System.gc();
  24. System.out.println(ref);
  25. //创建软引用
  26. SoftReference<myobject></myobject>softRef=newSoftReference<myobject></myobject>(
  27. newMyObject("Soft"));
  28. System.out.println(softRef.get());
  29. System.gc();
  30. System.out.println(softRef.get());
  31. //创建弱引用
  32. WeakReference<myobject></myobject>weakRef=newWeakReference<myobject></myobject>(
  33. newMyObject("Weak"));
  34. System.out.println("beforegc——"+weakRef.get());
  35. System.gc();
  36. System.out.println("aftergc——"+weakRef.get());
  37. //创建虚引用
  38. ReferenceQueue<myobject></myobject>rq=newReferenceQueue<myobject></myobject>();
  39. PhantomReference<myobject></myobject>phantomRef=newPhantomReference<myobject></myobject>(
  40. newMyObject("Phantom"),rq);
  41. System.out.println("beforegc——"+phantomRef.get());
  42. System.gc();
  43. System.out.println("aftergc——"+phantomRef.get());
  44. }
  45. }

输出如下:

Hard
null
Soft
Soft
回收对象:Hard
before gc —— Weak
after gc —— null
回收对象:Weak
before gc —— null
after gc —— null
回收对象:Phantom

以上我们创建了4种引用,依次是:强引用、软引用、弱引用、虚引用。

强引用即我们普通使用的申明方式,对于该引用,只有显示的赋值为null,gc才会视为回收对象。

软引用(SoftReference)是只有内存不足时,gc才会将它视为回收对象。

弱引用(WeakReference)是无论当前内存是否满足,gc都会去回收它。

虚引用(PahntomReference)实际是可以理解成“子虚乌有”的引用,目的仅仅是结合引用关联队列(ReferenceQueue),实现对对象引用关系的跟踪。

在MyObject类中finalize方法中,我们让它在被回收时打印一句话出来,从输出结果来看,我们可以很容易的理解GC这4种对象引用的不同处理方式。从中我们可以得到结论,System.gc()可以对弱引用和虚引用达到立竿见影的效果。

好了以上一点小建议、想法,希望能对你有所帮助!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值