您的位置:首页 > 编程语言 > Java开发

java的四种引用方式,以及垃圾回收器参数打印设置几种方式

2016-10-14 16:37 369 查看
技术点来自javase的java引用类型,jvm中垃圾回收的远离。

jdk1.0版本:

引用的集成体系:

                             Reference<T>

                                                  -----------FinalReference<T>

                                                  -----------PhantomReference<T>

                                                  -----------SoftReference<T>

                                                  -----------WeakReference<T>

⑴强引用(FinalReference)

          强引用是使用最普遍的引用。如果一个对象具有强引用,那垃圾回收器绝不会回收它。当内存空间不足,Java虚拟机宁愿抛出OutOfMemoryError错误,使程序异常终止,也不会靠随意回收具有强引用的对象来解决内存不足的问题。  ps:强引用其实也就是我们平时A a = new A()这个意思。

⑵软引用(SoftReference)
         如果一个对象只具有软引用,则内存空间足够,垃圾回收器就不会回收它;如果内存空间不足了,就会回收这些对象的内存。只要垃圾回收器没有回收它,该对象就可以被程序使用。软引用可用来实现内存敏感的高速缓存:

A a = new A();
//使用a
a.test();
//使用完了a,将它设置为soft引用类型,并且释放强引用
SoftReference sr = new SoftReference(a);
a = null;

//下次使用
if (sr != null) {
a = (A)sr.get();
a.test();
} else {
//GC由于低内存,已释放a,因此需要重新装载
a = new A();
a.test();
a = null;
sr = new SoftReference(a);
}
         软引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用所引用的对象被垃圾回收器回收,Java虚拟机就会把这个软引用加入到与之关联的引用队列中。

// 软引用
SoftReference<String> softReference = new SoftReference<String>("aaaaa");
String string = softReference.get();// 通过get方法获得强引用

System.out.println(string);

⑶弱引用(WeakReference)
          弱引用与软引用的区别在于:只具有弱引用的对象拥有更短暂的生命周期。在垃圾回收器线程扫描它所管辖的内存区域的过程中,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。不过,由于垃圾回收器是一个优先级很低的线程,因此不一定会很快发现那些只具有弱引用的对象。

          弱引用可以和一个引用队列(ReferenceQueue)联合使用,如果弱引用所引用的对象被垃圾回收,Java虚拟机就会把这个弱引用加入到与之关联的引用队列中。

// 弱引用
ReferenceQueue rq = new ReferenceQueue();
WeakReference<User> weakReference = new WeakReference<User>(u, rq);

u = null;
System.gc();

User user = weakReference.get();// 通过get方法获得强引用
if(user != null) {
user.fun();
} else {
System.out.println("aa");
}

gc会立马回收弱引用的对象,并且ReferenceQueue中会立马长度加1.

⑷虚引用(PhantomReference)

         “虚引用”顾名思义,就是形同虚设,与其他几种引用都不同,虚引用并不会决定对象的生命周期。如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收器回收。

        虚引用主要用来跟踪对象被垃圾回收器回收的活动。虚引用与软引用和弱引用的一个区别在于:虚引用必须和引用队列(ReferenceQueue)联合使用。当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之 关联的引用队列中。

ReferenceQueue queue = new ReferenceQueue ();

PhantomReference pr = new PhantomReference (object, queue);

PS:对应咱们做应用开发的程序员用的最多的就是强引用了,好处就是不会频繁的对内存进行申请开销,坏处就是服务端越来越笨重,需要的机器性能越来越高。其他的软引用,弱引用,虚引用用在特殊的用途上面。

例如:

缓存的实现,开源的有OSCache,EnCache,里面用到了很多软引用的实例。

垃圾回收的一些参数配置:

JVM提供了大量命令行参数,打印信息,供调试使用。主要有以下一些:

-XX:+PrintGC

输出形式:[GC 118250K->113543K(130112K), 0.0094143 secs]

                [Full GC 121376K->10414K(130112K), 0.0650971 secs]

-XX:+PrintGCDetails

输出形式:[GC [DefNew: 8614K->781K(9088K), 0.0123035 secs] 118250K->113543K(130112K), 0.0124633 secs]

                [GC [DefNew: 8614K->8614K(9088K), 0.0000665 secs][Tenured: 112761K->10414K(121024K), 0.0433488 secs] 121376K->10414K(130112K), 0.0436268 secs]

-XX:+PrintGCTimeStamps -XX:+PrintGC:PrintGCTimeStamps可与上面两个混合使用

输出形式:11.851: [GC 98328K->93620K(130112K), 0.0082960 secs]

-XX:+PrintGCApplicationConcurrentTime:打印每次垃圾回收前,程序未中断的执行时间。可与上面混合使用

输出形式:Application time: 0.5291524 seconds

-XX:+PrintGCApplicationStoppedTime:打印垃圾回收期间程序暂停的时间。可与上面混合使用

输出形式:Total time for which application threads were stopped: 0.0468229 seconds

-XX:+PrintHeapAtGC:打印GC前后的详细堆栈信息

输出形式:

34.702: [GC {Heap before gc invocations=7:def new generation   total 55296K, used 52568K [0x1ebd0000, 0x227d0000, 0x227d0000)eden space 49152K, 99% used [0x1ebd0000, 0x21bce430, 0x21bd0000)from space 6144K, 55% used [0x221d0000, 0x22527e10, 0x227d0000)to  
space 6144K,   0% used [0x21bd0000, 0x21bd000
be68
0, 0x221d0000)tenured generation   total 69632K, used 2696K [0x227d0000, 0x26bd0000, 0x26bd0000)the space 69632K,   3% used [0x227d0000, 0x22a720f8, 0x22a72200, 0x26bd0000)compacting perm gen total 8192K, used 2898K
[0x26bd0000, 0x273d0000, 0x2abd0000)the space 8192K, 35% used [0x26bd0000, 0x26ea4ba8, 0x26ea4c00, 0x273d0000)ro space 8192K, 66% used [0x2abd0000, 0x2b12bcc0, 0x2b12be00, 0x2b3d0000)rw space 12288K, 46% used [0x2b3d0000, 0x2b972060, 0x2b972200, 0x2bfd0000)34.735:
[DefNew: 52568K->3433K(55296K), 0.0072126 secs] 55264K->6615K(124928K)Heap after gc invocations=8:def new generation   total 55296K, used 3433K [0x1ebd0000, 0x227d0000, 0x227d0000)eden space 49152K,   0% used [0x1ebd0000, 0x1ebd0000, 0x21bd0000)from space
6144K, 55% used [0x21bd0000, 0x21f2a5e8, 0x221d0000)to   space 6144K,   0% used [0x221d0000, 0x221d0000, 0x227d0000)

tenured generation   total 69632K, used 3182K [0x227d0000, 0x26bd0000, 0x26bd0000)the space 69632K,   4% used [0x227d0000, 0x22aeb958, 0x22aeba00, 0x26bd0000)compacting perm gen total 8192K, used 2898K [0x26bd0000, 0x273d0000, 0x2abd0000)the space 8192K, 35%
used [0x26bd0000, 0x26ea4ba8, 0x26ea4c00, 0x273d0000)ro space 8192K, 66% used [0x2abd0000, 0x2b12bcc0, 0x2b12be00, 0x2b3d0000)rw space 12288K, 46% used [0x2b3d0000, 0x2b972060, 0x2b972200, 0x2bfd0000)}, 0.0757599 secs]

-Xloggc:filename:与上面几个配合使用,把相关日志信息记录到文件以便分析。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐