java引用

前言:

在平时的开发中,我们每天要new无法的对象,这些对象存在于jvm的堆内存中,而他们的生老病死生命周期全部归JVM控制。不同的对象引用的,其生命周期也有显著的不同,如何通过其他不用强度的引用来避免jvm的最大隐患:out of Memory?本篇博客将会介绍java的四种不同的引用类型,来看一下在GC的前后他们将会经历什么样的变化?经历怎样的事情?

目录

java引用强度图

一:虚引用

二:弱引用

三:软引用

四:强引用

java引用强度图

1:虚引用

 1.1简介:虚引用是所有引用中强度最弱的,它完全类似于没有引用,在java.reflact.PhantomReference类中实现。虚引用对象本身没有太大影响,对象甚至感觉不到虚引用的存在。如果一个对象存在虚引用,那么它和没有引用的效果大致相同,虚引用无法引用任何堆中的对象

作用:虚引用主要用于跟踪对象被JVM垃圾回收的状态,可以通过它来收集GC的行为。可以通过检查与虚引用关联的引用队列中是否已经包含指定的虚引用,从而了解虚引用所引用的对象是否被回收。

注意:虚引用无法单独使用,虚引用必须和引用队列(ReferenceQueue)联合使用.被虚引用所引用对象被垃圾回收后,虚引用将被添加到引用队列中。

 

 public static void  main(String[] args) {
        
        //引用队列
        ReferenceQueue<String> rq = new ReferenceQueue<>();

        PhantomReference<String>  phantomReference= new PhantomReference<>(new String("test"), rq);

        System.out.println("GC前:"+phantomReference.get());

        System.gc();

        System.runFinalization();

        Reference<? extends String> reference = rq.poll();
        
        System.out.println(reference==phantomReference);

    }

首先,我们在idea中运行的程序中添加GC参数:-XX:+PrintGCDetails,看一下具体的GC细节:

GC前:null
[Full GC (System.gc()) [Tenured: 0K->531K(10944K), 0.0037042 secs] 1221K->531K(15872K), [Metaspace: 1910K->1910K(4480K)], 0.0038045 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
true
Heap
def new generation total 4992K, used 209K [0x06800000, 0x06d60000, 0x0bd50000)
eden space 4480K, 4% used [0x06800000, 0x06834678, 0x06c60000)
from space 512K, 0% used [0x06c60000, 0x06c60000, 0x06ce0000)
to space 512K, 0% used [0x06ce0000, 0x06ce0000, 0x06d60000)
tenured generation total 10944K, used 531K [0x0bd50000, 0x0c800000, 0x16800000)
the space 10944K, 4% used [0x0bd50000, 0x0bdd4c48, 0x0bdd4e00, 0x0c800000)
Metaspace used 1948K, capacity 2280K, committed 2368K, reserved 4480K

程序输出如下,GC前:因为虚引用无法引用任何实体对象,所以输出为null。而在GC后,jvm会将被回收的对象添加到引用队列中,我们直接取队列中的对象和虚引用比较比较,发现输出的是true,这就表示他们是等同的。而接下来的输出:可以看到在eden区,有4%的占有量,这说明虚引用首先进入的就时eden区,然后在其他两个survior区占有的空间都是为0%。

2:弱引用

简介:弱引用和虚引用有点类似,不同之处在于虚引用锁引用的对象生存期比虚引用长一点。虚引用在java.reflact.WeakReference类实现。在系统进行垃圾回收的时候,不管系统内存是否足够,总是回收该对象所占用的内存.但是弱引用的强度是要大于虚引用的

2.1:我们来写个程序验证一下

public class WeakReferenceTest {

public static void main(String[] args) {

WeakReference<String> weakReference = new WeakReference<String>(new String("test"));

System.out.println("GC前:"+weakReference.get());

System.gc();

System.runFinalization();

System.out.println("GC后:"+weakReference.get());

}
}

上面的代码我们新建一个虚引用,让它关联一个字符串"test",首先我们来输出这个虚引用的值,接着调取系统的Gc程序,让它发生一次gc,再输出虚引用的值,经过测试。为了方便看出Gc发生了什么,我们在idea运行的配置中的运行窗口添加“-XX:PrintGC”,(如果要看GC细节,比如老年代和新生代信息就用“-XX:+PrintGCDetails)参数,看看接下来会输出什么?

 可以看出程序经过了一次FullGc,然后取得虚引用的值最后为null,这说明了虚引用被回收了,而此时程序还是有闲余空间的,这就证明了虚引用在gc的时候是一定会被回收的!

 

3:软引用

简介:软引用比弱引用的强度高一点,它是通过java.reflact.SoftReference来实现。对于软引用来说,当系统内存空间足够时,它不会被系统回收,程序中改对象的引用也是有效的。而当系统的内存空间不够时,系统将会回收它。

作用:软引用是强引用最好的替代,它一定程度上可以避免系统内存不足的异常,可以充分使用软引用来解决内存紧张的问题。

 public static void main(String[] args) {

        SoftReference<Person> persons = new SoftReference<Person>(new Person("wyq",25));


        System.out.println("Xmx=" + (Runtime.getRuntime().maxMemory( ) / 1024.0 / 1024)*2 + "M");     //系统堆的最大空间

        System.out.println("free mem=" + Runtime.getRuntime().freeMemory() / 1024.0 / 1024 + "M");   //系统的空闲空间

        System.out.println("total mem=" + Runtime.getRuntime().totalMemory() / 1024.0 / 1024 + "M");   //当前可用的总空间

        System.out.println(persons.get().getName());

        //垃圾回收 gc
        System.gc();

        System.runFinalization();

        System.out.println(persons.get().getName());
        

    }

上面的程序中,我新建一个软引用,引用对象person,然后输出堆的最大内存和空闲内存和可用内存,

Xmx=495.0M
free mem=14.306655883789062M
total mem=15.5M
wyq
[Full GC (System.gc()) [Tenured: 0K->566K(10944K), 0.0032913 secs] 1221K->566K(15872K), [Metaspace: 1954K->1954K(4480K)], 0.0033766 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
wyq
Heap
 def new generation   total 4992K, used 209K [0x06800000, 0x06d60000, 0x0bd50000)
  eden space 4480K,   4% used [0x06800000, 0x068346e0, 0x06c60000)
  from space 512K,   0% used [0x06c60000, 0x06c60000, 0x06ce0000)
  to   space 512K,   0% used [0x06ce0000, 0x06ce0000, 0x06d60000)
 tenured generation   total 10944K, used 566K [0x0bd50000, 0x0c800000, 0x16800000)
   the space 10944K,   5% used [0x0bd50000, 0x0bddda18, 0x0bdddc00, 0x0c800000)
 Metaspace       used 1992K, capacity 2280K, committed 2368K, reserved 4480K

可以看出系统的freememory还有14.3M,这说明系统的堆内存是足够有剩余的,这时候就不会回收软引用,在经历过一次Full GC后仍然输出了引用对象,而接下来我们来设置一下堆内存为2m(-XX:MaxMetaspaceSize=2m),看一下系统在堆内存不足的情况下会发生什么?

在使用参数:-XX:MaxPermSize=2m,运行程序的时候会报:Java HotSpot(TM) Client VM warning: ignoring option MaxPermSize=2m; support was removed in 8.0,所以我们必须要用参数:-XX:MaxMetaspaceSize=2m 使堆内存的大小设为2m:

 程序输出如下:

Xmx=247M
free mem=14.306983947753906M
total mem=15.5M
wyq
[Full GC (System.gc()) [Tenured: 0K->566K(10944K), 0.0025855 secs] 1221K->566K(15872K), [Metaspace: 1976K->1976K(4480K)], 0.0026503 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Metadata GC Threshold) [Tenured: 566K->568K(10944K), 0.0031402 secs] 746K->568K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0032499 secs] [Times: user=0.02 sys=0.00, real=0.02 secs]
[Full GC (Last ditch collection) [Tenured: 568K->568K(10944K), 0.0019662 secs] 568K->568K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0020254 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Metadata GC Threshold) [Tenured: 568K->554K(10944K), 0.0020574 secs] 568K->554K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0020878 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Last ditch collection) [Tenured: 554K->554K(10944K), 0.0014246 secs] 554K->554K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0014499 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Metadata GC Threshold) [Tenured: 554K->554K(10944K), 0.0013883 secs] 554K->554K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0014151 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Last ditch collection) [Tenured: 554K->554K(10944K), 0.0013259 secs] 554K->554K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0013492 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Metadata GC Threshold) [Tenured: 554K->553K(10944K), 0.0015403 secs] 554K->553K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0015679 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Last ditch collection) [Tenured: 553K->553K(10944K), 0.0013690 secs] 553K->553K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0013942 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Metadata GC Threshold) [Tenured: 553K->553K(10944K), 0.0013559 secs] 553K->553K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0013832 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Last ditch collection) [Tenured: 553K->553K(10944K), 0.0017625 secs] 553K->553K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0017886 secs] [Times: user=0.02 sys=0.00, real=0.02 secs]
[Full GC (Metadata GC Threshold) [Tenured: 553K->552K(10944K), 0.0022259 secs] 553K->552K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0022603 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Last ditch collection) [Tenured: 552K->552K(10944K), 0.0014301 secs] 552K->552K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0014554 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Metadata GC Threshold) [Tenured: 552K->552K(10944K), 0.0014495 secs] 552K->552K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0014795 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Last ditch collection) [Tenured: 552K->552K(10944K), 0.0013472 secs] 552K->552K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0013690 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Metadata GC Threshold) [Tenured: 552K->552K(10944K), 0.0019808 secs] 552K->552K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0020195 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Last ditch collection) [Tenured: 552K->552K(10944K), 0.0019117 secs] 552K->552K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0019461 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Metadata GC Threshold) [Tenured: 552K->552K(10944K), 0.0019820 secs] 552K->552K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0020203 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Last ditch collection) [Tenured: 552K->552K(10944K), 0.0021647 secs] 552K->552K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0022038 secs] [Times: user=0.01 sys=0.00, real=0.02 secs]
[Full GC (Metadata GC Threshold) [Tenured: 552K->552K(10944K), 0.0017972 secs] 552K->552K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0018296 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Last ditch collection) [Tenured: 552K->552K(10944K), 0.0014507 secs] 552K->552K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0014767 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Metadata GC Threshold) [Tenured: 552K->552K(10944K), 0.0014021 secs] 552K->552K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0014274 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Last ditch collection) [Tenured: 552K->552K(10944K), 0.0013267 secs] 552K->552K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0013516 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Metadata GC Threshold) [Tenured: 552K->552K(10944K), 0.0014384 secs] 552K->552K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0014696 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Last ditch collection) [Tenured: 552K->552K(10944K), 0.0013251 secs] 552K->552K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0013492 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Metadata GC Threshold) [Tenured: 552K->552K(10944K), 0.0019417 secs] 552K->552K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0019832 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Last ditch collection) [Tenured: 552K->552K(10944K), 0.0021817 secs] 552K->552K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0022255 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Metadata GC Threshold) [Tenured: 552K->552K(10944K), 0.0018351 secs] 552K->552K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0018782 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Last ditch collection) [Tenured: 552K->552K(10944K), 0.0014325 secs] 552K->552K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0014629 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Metadata GC Threshold) [Tenured: 552K->552K(10944K), 0.0014487 secs] 642K->552K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0014767 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Last ditch collection) [Tenured: 552K->552K(10944K), 0.0016133 secs] 552K->552K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0016457 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Metadata GC Threshold) [Tenured: 552K->552K(10944K), 0.0014365 secs] 642K->552K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0014676 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Last ditch collection) [Tenured: 552K->552K(10944K), 0.0013555 secs] 552K->552K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0013800 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Metadata GC Threshold) [Tenured: 552K->552K(10944K), 0.0020428 secs] 552K->552K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0020826 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Last ditch collection) [Tenured: 552K->552K(10944K), 0.0019666 secs] 552K->552K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0020053 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Metadata GC Threshold) [TenuredException in thread "Monitor Ctrl-Break" : 552K->552K(10944K), 0.0016875 secs] 642K->552K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0017155 secs] [Times: user=0.02 sys=0.00, real=0.01 secs]
[Full GC (Last ditch collection) [Tenured: 552K->552K(10944K), 0.0013970 secs] 552K->552K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0014207 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Metadata GC Threshold) [Tenured: 552K->552K(10944K), 0.0013378 secs] 552K->552K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0013654 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Last ditch collection) [Tenured: 552K->552K(10944K), 0.0013137 secs] 552K->552K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0013382 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Metadata GC Threshold) [Tenured: 552K->552K(10944K), 0.0015111 secs] 642K->552K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0015391 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Last ditch collection) [Tenured: 552K->552K(10944K), 0.0012758 secs] 552K->552K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0012971 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Metadata GC Threshold) [Tenured: 552K->552K(10944K), 0.0014822 secs] 642K->552K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0015122 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Last ditch collection) [Tenured: 552K->552K(10944K), 0.0012695 secs] 552K->552K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0012940 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Metadata GC Threshold) [Tenured: 552K->552K(10944K), 0.0013599 secs] 552K->552K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0013879 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Last ditch collection) [Tenured: 552K->552K(10944K), 0.0012738 secs] 552K->552K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0012971 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Metadata GC Threshold) [Tenured: 552K->552K(10944K), 0.0015655 secs] 641K->552K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0016074 secs] [Times: user=0.01 sys=0.00, real=0.02 secs]
[Full GC (Last ditch collection) [Tenured: 552K->552K(10944K), 0.0016204 secs] 552K->552K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0016528 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Metadata GC Threshold) [Tenured: 552K->552K(10944K), 0.0015620 secs] 552K->552K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0015908 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Last ditch collection) [Tenured: 552K->552K(10944K), 0.0012647 secs] 552K->552K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0012857 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
GC after:null
[Full GC (Metadata GC Threshold) [Tenured: 552K->552K(10944K), 0.0013717 secs] 641K->552K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0013997 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Last ditch collection) [Tenured: 552K->552K(10944K), 0.0017515 secs] 552K->552K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0017882 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Metadata GC Threshold) [Tenured: 552K->551K(10944K), 0.0021446 secs] 552K->551K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0021861 secs] [Times: user=0.02 sys=0.00, real=0.00 secs]
[Full GC (Last ditch collection) [Tenured: 551K->551K(10944K), 0.0014349 secs] 551K->551K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0014649 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Metadata GC Threshold) [Tenured: 551K->551K(10944K), 0.0013145 secs] 551K->551K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0013476 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Last ditch collection) [Tenured: 551K->551K(10944K), 0.0013476 secs] 551K->551K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0013717 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Metadata GC Threshold) [Tenured: 551K->551K(10944K), 0.0012908 secs] 551K->551K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0013169 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Last ditch collection) [Tenured: 551K->551K(10944K), 0.0012647 secs] 551K->551K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0012880 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Metadata GC Threshold) [Tenured: 551K->551K(10944K), 0.0015951 secs] 551K->551K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0016315 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Last ditch collection) [Tenured: 551K->551K(10944K), 0.0013820 secs] 551K->551K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0014396 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Metadata GC Threshold) [Tenured: 551K->551K(10944K), 0.0018561 secs] 551K->551K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0018896 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Last ditch collection) [Tenured: 551K->551K(10944K), 0.0020562 secs] 551K->551K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0020909 secs] [Times: user=0.02 sys=0.00, real=0.00 secs]
[Full GC (Metadata GC Threshold) [Tenured: 551K->551K(10944K), 0.0017207 secs] 551K->551K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0017503 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Last ditch collection) [Tenured: 551K->551K(10944K), 0.0013883 secs] 551K->551K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0014187 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Metadata GC Threshold) [Tenured: 551K->551K(10944K), 0.0019646 secs] 551K->551K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0019934 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Last ditch collection) [Tenured: 551K->551K(10944K), 0.0015501 secs] 551K->551K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0015813 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Metadata GC Threshold) [Tenured: 551K->552K(10944K), 0.0013863 secs] 641K->552K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0014905 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Last ditch collection) [Tenured: 552K->552K(10944K), 0.0012971 secs] 552K->552K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0013196 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Metadata GC Threshold) [Tenured: 552K->552K(10944K), 0.0013255 secs] 552K->552K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0013528 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Last ditch collection) [Tenured: 552K->552K(10944K), 0.0012411 secs] 552K->552K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0012651 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Metadata GC Threshold) [Tenured: 552K->552K(10944K), 0.0013595 secs] 552K->552K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0013946 secs] [Times: user=0.02 sys=0.00, real=0.00 secs]
[Full GC (Last ditch collection) [Tenured: 552K->552K(10944K), 0.0021316 secs] 552K->552K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0021726 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Metadata GC Threshold) [Tenured: 552K->551K(10944K), 0.0022524 secs] 552K->551K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0022867 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Last ditch collection) [Tenured: 551K->551K(10944K), 0.0014570 secs] 551K->551K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0014854 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Metadata GC Threshold) [Tenured: 551K->551K(10944K), 0.0014171 secs] 551K->551K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0014479 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Last ditch collection) [Tenured: 551K->551K(10944K), 0.0012987 secs] 551K->551K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0013247 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Metadata GC Threshold) [Tenured: 551K->551K(10944K), 0.0017317 secs] 641K->551K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0017625 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Last ditch collection) [Tenured: 551K->551K(10944K), 0.0015099 secs] 551K->551K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0015355 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Metadata GC Threshold) [Tenured: 551K->551K(10944K), 0.0014321 secs] 641K->551K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0014605 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Last ditch collection) [Tenured: 551K->551K(10944K), 0.0013208 secs] 551K->551K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0013429 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Metadata GC Threshold) [Tenured: 551K->551K(10944K), 0.0022030 secs] 551K->551K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0022417 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Last ditch collection) [Tenured: 551K->551K(10944K), 0.0019626 secs] 551K->551K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0019970 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Metadata GC Threshold) [Tenured: 551K->551K(10944K), 0.0019622 secs] 551K->551K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0019982 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Last ditch collection) [Tenured: 551K->551K(10944K), 0.0019180 secs] 551K->551K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0019528 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Metadata GC Threshold) [Tenured: 551K->551K(10944K), 0.0019745 secs] 551K->551K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0020112 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Last ditch collection) [Tenured: 551K->551K(10944K), 0.0018916 secs] 551K->551K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0019295 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Metadata GC Threshold) [Tenured: 551K->551K(10944K), 0.0014495 secs] 551K->551K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0014779 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Last ditch collection) [Tenured: 551K->551K(10944K), 0.0016109 secs] 551K->551K(15936K), [Metaspace: 1997K->1997K(4480K)], 0.0016382 secs] [Times: user=0.02 sys=0.00, real=0.00 secs]
Heap
def new generation total 4992K, used 0K [0x07000000, 0x07560000, 0x0c550000)
eden space 4480K, 0% used [0x07000000, 0x07000000, 0x07460000)
from space 512K, 0% used [0x07460000, 0x07460000, 0x074e0000)
to space 512K, 0% used [0x074e0000, 0x074e0000, 0x07560000)
tenured generation total 10944K, used 551K [0x0c550000, 0x0d000000, 0x17000000)
the space 10944K, 5% used [0x0c550000, 0x0c5d9c30, 0x0c5d9e00, 0x0d000000)
Metaspace used 1997K, capacity 2030K, committed 2048K, reserved 4480K

看程序输出可以看出在GC后,输出为null,这表示系统在内存不足的情况下,会清除软引用!

4:强引用

简介:强引用很常见,在平时的程序中,我们新new一个对象,比如 Object object = new Object();那么这个object就是指向object对象的 强引用。强引用的特点就是:被引用的java对象绝对不会被垃圾回收机制回收,即使系统的内存非常紧张,即使java以后也用不到,jvm不会回收强引用所引用的java对象。

注意:java内存泄露的问题都是由强引用引起的,其他类型的引用不会引起内存泄漏问题。

我们用程序来模拟一个内存溢出的程序,创建一个list,然后用无限循环的方式,给list不断添加对象,这样就会产生内存溢出,我们在程序中添加参数-XX:+PrintGCDetails,这样就可以打印出GC日志了,然后我们来分析一下日志:

public static void main(String[] args) {

    ArrayList<Person> people = new ArrayList<>();

    while (true){
        people.add(new Person());
    }
}

上面的程序一定会发生内存溢出的,然后我们来看一下GC的具体日志:

[GC (Allocation Failure) [DefNew: 4158K->512K(4928K), 0.0068811 secs] 4158K->2619K(15872K), 0.0069265 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[GC (Allocation Failure) [DefNew: 4233K->512K(4928K), 0.0105040 secs] 6340K->5226K(15872K), 0.0105423 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[GC (Allocation Failure) [DefNew: 3900K->512K(4928K), 0.0094023 secs] 8615K->8513K(15872K), 0.0094339 secs] [Times: user=0.00 sys=0.02, real=0.01 secs] 
[GC (Allocation Failure) [DefNew: 4928K->512K(4928K), 0.0095223 secs][Tenured: 12400K->10567K(12480K), 0.0375374 secs] 12929K->10567K(17408K), [Metaspace: 2021K->2021K(4480K)], 0.0472042 secs] [Times: user=0.05 sys=0.00, real=0.05 secs] 
[GC (Allocation Failure) [DefNew: 7168K->832K(8000K), 0.0204949 secs] 17735K->17735K(25616K), 0.0205324 secs] [Times: user=0.01 sys=0.01, real=0.03 secs] 
[GC (Allocation Failure) [DefNew: 8000K->832K(8000K), 0.0186226 secs][Tenured: 24071K->19627K(24160K), 0.0561055 secs] 24903K->19627K(32160K), [Metaspace: 2021K->2021K(4480K)], 0.0748636 secs] [Times: user=0.06 sys=0.00, real=0.08 secs] 
[GC (Allocation Failure) [DefNew: 13184K->1600K(14784K), 0.0234365 secs] 32811K->32679K(47500K), 0.0234965 secs] [Times: user=0.03 sys=0.00, real=0.03 secs] 
[GC (Allocation Failure) [DefNew: 9990K->1600K(14784K), 0.0415187 secs][Tenured: 39302K->36154K(39372K), 0.1154882 secs] 41070K->36154K(54156K), [Metaspace: 2021K->2021K(4480K)], 0.1572450 secs] [Times: user=0.16 sys=0.00, real=0.16 secs] 
[GC (Allocation Failure) [DefNew: 24128K->3008K(27136K), 0.0740169 secs] 60282K->60281K(87396K), 0.0740484 secs] [Times: user=0.06 sys=0.00, real=0.08 secs] 
[GC (Allocation Failure) [DefNew: 27136K->3008K(27136K), 0.0647559 secs][Tenured: 81401K->66599K(81408K), 0.3430406 secs] 84409K->66599K(108544K), [Metaspace: 2021K->2021K(4480K)], 0.4081747 secs] [Times: user=0.28 sys=0.03, real=0.41 secs] 
[GC (Allocation Failure) [DefNew: 44544K->5504K(50048K), 0.1184038 secs] 111143K->111143K(161048K), 0.1184389 secs] [Times: user=0.11 sys=0.02, real=0.13 secs] 
[GC (Allocation Failure) [DefNew: 31236K->5504K(50048K), 0.1688689 secs][Tenured: 131243K->120723K(131352K), 0.3622913 secs] 136875K->120723K(181400K), [Metaspace: 2021K->2021K(4480K)], 0.5315154 secs] [Times: user=0.50 sys=0.02, real=0.53 secs] 
[GC (Allocation Failure) [DefNew (promotion failed) : 69952K->78656K(78656K), 0.1706140 secs][Tenured: 174783K->166638K(174784K), 0.4217281 secs] 190675K->166638K(253440K), [Metaspace: 2021K->2021K(4480K)], 0.5923886 secs] [Times: user=0.56 sys=0.01, real=0.59 secs] 
[GC (Allocation Failure) [DefNew: 69952K->69952K(78656K), 0.0000142 secs][Tenured: 166638K->145825K(174784K), 0.4221919 secs] 236590K->200534K(253440K), [Metaspace: 2021K->2021K(4480K)], 0.4222538 secs] [Times: user=0.42 sys=0.00, real=0.42 secs] 
[Full GC (Allocation Failure) [Tenured: 174783K->174783K(174784K), 0.5150662 secs] 253439K->253439K(253440K), [Metaspace: 2021K->2021K(4480K)], 0.5151033 secs] [Times: user=0.50 sys=0.00, real=0.50 secs] 
[Full GC (Allocation Failure) [Tenured: 174783K->174783K(174784K), 0.4917999 secs] 253439K->253439K(253440K), [Metaspace: 2021K->2021K(4480K)], 0.4918283 secs] [Times: user=0.50 sys=0.00, real=0.50 secs] 
[Full GC (Allocation Failure) [Tenured: 174783K->174769K(174784K), 0.6302426 secs] 253439K->253425K(253440K), [Metaspace: 2021K->2021K(4480K)], 0.6302690 secs] [Times: user=0.63 sys=0.00, real=0.63 secs] 
[Full GC (Allocation Failure) [Tenured: 174784K->174784K(174784K), 0.6786191 secs] 253439K->253439K(253440K), [Metaspace: 2021K->2021K(4480K)], 0.6786531 secs] [Times: user=0.61 sys=0.06, real=0.67 secs] 
[Full GC (Allocation Failure) [Tenured: 174784K->174784K(174784K), 0.7245613 secs] 253439K->253439K(253440K), [Metaspace: 2021K->2021K(4480K)], 0.7245893 secs] [Times: user=0.72 sys=0.02, real=0.74 secs] 
[Full GC (Allocation Failure) [TenuredException in thread "main" : 174784K->7929K(174784K), 0.0491088 secs] 253439K->7929K(253440K), [Metaspace: 2021K->2021K(4480K)], 0.0491376 secs] [Times: user=0.05 sys=0.00, real=0.05 secs] 
Heap
java.lang.OutOfMemoryError: Java heap space
 def new generation   total 78656K, used 1945K [0x06e00000, 0x0c350000, 0x0c350000)
    at com.wyq.ReferenceStrength.StrongReferenceTest.main(StrongReferenceTest.java:17)
  eden space 69952K,   2% used [0x06e00000, 0x06fe67c0, 0x0b250000)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  from space 8704K,   0% used [0x0bad0000, 0x0bad0000, 0x0c350000)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
  to   space 8704K,   0% used [0x0b250000, 0x0b250000, 0x0bad0000)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
 tenured generation   total 174784K, used 7929K [0x0c350000, 0x16e00000, 0x16e00000)
    at java.lang.reflect.Method.invoke(Method.java:497)
   the space 174784K,   4% used [0x0c350000, 0x0cb0e410, 0x0cb0e600, 0x16e00000)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
 Metaspace       used 2041K, capacity 2280K, committed 2368K, reserved 4480K

  这里稍微解释一下:Allocation Failure:表示本次GC是因为年轻代中没有任何合适的区域能够存放需要分配的数据结构而引起。其中DefNew表示:使用的是ParallelNew垃圾收集器的是年轻代 defnew这个名字代表的是: 单线程(single-threaded), 采用标记复制(mark-copy)算法的, 使整个JVM暂停运行(stop-the-world)的年轻代(Young generation) 垃圾收集器(garbage collector).。

DefNew: 4158K->512K(4928K) 表示GC前该内存区域已使用容量->GC后该内存区域已使用容量(该内存区域总容量)。 分析数据可以看出GC后内存的使用量是直线上升,这是因为新new的person对象都进入了年轻代,占据了内存。然后到了69952K->69952K(78656K),这时就表示可用的内存已经没有了.此时进入了年老代。(内存先在survior区(1区或2区都随机的),满了之后进入老年代) 从这里可以看出,年老代已经满了,GC前和GC后内存可用空间都是满的。[Tenured: 174783K->174783K(174784K)],就会发生out of memory!

 总结:本篇博客介绍了java4种引用的特点以及在GC时候不同的表现行为以及如何使用,在平时的工作中,我们基本用不到这些其他的引用,但是了解GC原理,一旦程序体量变大了,就得深入了解GC,以及如何在程序中使用不同的引用,这是值得思考的!

 

原文地址:https://www.cnblogs.com/wyq178/p/9427987.html