`

引用包java.lang.ref中几种引用详解 2 -- 测试代码

 
阅读更多

上一篇: 引用包java.lang.ref中几种引用详解 http://jackyin5918.iteye.com/blog/1881901

这里是一些测试代码:

测试 各个引用创建大量对象时是否导致 Heap 不足异常?

类型是否抛出异常示例代码运行结果
StrongReference 抛出异常 见清单 6 Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
SoftReference 不抛异常,之前的引用自动清空并返回 null 见清单 7 null
WeakReference 同上 见清单 8 null
PhantomReference 抛出异常 见清单 9 Exception in thread "main" java.lang.OutOfMemoryError: Java heap space



清单 7

				
				public static void main(String[] args) { 
 Bean[] referent = new Bean[100000]; 
 for (int i=0;i<referent.length;i++){ 
 referent[i] = new Bean("mybean:" + i,100);// 抛 Exception 
 } 
 } 

 

总结:在新开辟 100000 个 Bean 对象时,由于强引用永远不会被系统回收,当最大 Heap 阈值达到 2m 时,系统就会报出 Heap 不足的异常。


清单 8

				
				public static void main(String[] args) { 
 Reference<Bean>[] referent = new SoftReference[100000]; 
 for (int i=0;i<referent.length;i++){ 
 referent[i] = new SoftReference<Bean>(new Bean("mybean:" + i,100)); 
 } 

 System.out.println(referent[100].get());// “null”
 } 

 

总结:在新开辟 100000 个 Bean 对象时,由于软引用会视内存使用情况来判断是否自动回收,所以当最大 Heap 阈值达到 2m 时,系统自动回收最前面开辟的对象,取第 100 个对象时,返回为 null。


清单 9

				
 public static void main(String[] args) { 
 Reference<Bean>[] referent = new WeakReference[100000]; 
 for (int i=0;i<referent.length;i++){ 
 referent[i] = new WeakReference<Bean>(new Bean("mybean:" + i,100)); 
 } 

 System.out.println(referent[100].get());// “null”
 } 

 

总结:WeakReference 与 SoftReference 具有相同的特性,也会视内存使用情况来判断是否自动回收。取第 100 个对象时,返回为 null。


清单 10

				
public static void main(String[] args) { 
 Reference<Bean>[] referent = new PhantomReference[100000]; 
 ReferenceQueue<Bean> queue = new ReferenceQueue<Bean>(); 
 for (int i=0;i<referent.length;i++){ 
 referent[i] = new PhantomReference<Bean>(new Bean("mybean:" + i,100), 
 queue);// throw Exception 
 } 

 System.out.println(referent[100].get()); 
 } 

 

总结:PhantomReference 类似强引用,它不会自动根据内存情况自动对目标对象回收,所以这里在 Heap 里不断开辟新空间,当达到 2m 阈值时,系统报出 OutOfMemoryError 异常。

自己的测试代码:

a.强引用,内存不足时异常,OutOfMemory

package test.reference;


/**
 * 测试强引用
 * 总结:在新开辟 10000000 个 Bean 对象时,由于强引用永远不会被系统回收,
 * 当最大 Heap 阈值达到 5m 时,系统就会报出 Heap 不足的异常。
 * 
 * 创建大量对象,这里在myeclipse中将JVM的参数设置为 -Xmx5m -Xms5m(能设置的最小内存了,再小就报错了)
 *  Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
 *	at test.reference.TestCommonReference.main(TestCommonReference.java:17)
 *
 */
public class TestCommonReference
{
  public static void main(String[] args)
  {
    int iCount = 10000000;
    Bean[] beans = new Bean[iCount];
    for (int i=0;i<iCount;i++)
    {
      beans[i] = new Bean("Jack-"+i,i);
    }
  }
}

 

 b. 软引用测试

package test.reference;

import java.lang.ref.Reference;
import java.lang.ref.SoftReference;

/**
 * 软引用使用 get() 方法取得对象的强引用从而访问目标对象。
 * 软引用所指向的对象按照 JVM 的使用情况(Heap 内存是否临近阈值)来决定是否回收。
 * 软引用可以避免 Heap 内存不足所导致的异常。
 * 
 * 创建大量对象,这里在myeclipse中将JVM的参数设置为 -Xmx5m -Xms5m(最小内存了,再小就报错了)
 *
 */
public class TestSoftReferenceM
{
  public static void main(String[] args)
  {
    int iCount = 1000000;
    /**
     * 当iCount取10万时,程序正常,references[100].get()为null,因为当heap内存不够是SoftReference对象自动被回收了,
     * 这里显然references[100]的软引用对象被回收了
     * 但,当iCount取100万时,
     * 程序也报异常:OutOfMemoryError: Java heap space
     * 这里是因为references数组太大了,而每一个references元素是一个SoftReference<Bean>对象,这个是强引用,不能释放
     */
    Reference<Bean>[] references = new SoftReference[iCount];//不能创建泛型数组,所以new SoftReference<Bean>[iCount];//错误
    for(int i=0;i<iCount;i++)
    {
      references[i] = new SoftReference<Bean>(new Bean("Jack_" + i,i));
    }
    System.out.println(references[100].get());
    
  }
}

 

c:弱引用

package test.reference;

import java.lang.ref.Reference;
import java.lang.ref.WeakReference;

/**
 * 总结:WeakReference 与 SoftReference 具有相同的特性,
 * 也会视内存使用情况来判断是否自动回收。取第 100 个对象时,返回为 null。
 * 
 * 弱引用所指向的对象只要进行 GC,就会自动进行回收,get() 返回 null。
 * 弱引用使用 get() 方法取得对象的强引用从而访问目标对象。
 * 一旦系统内存回收,无论内存是否紧张,弱引用指向的对象都会被回收。
 * 弱引用也可以避免 Heap 内存不足所导致的异常。
 * 
 * 创建大量对象,这里在myeclipse中将JVM的参数设置为 -Xmx5m -Xms5m(最小内存了,再小就报错了)
 *
 */
public class TestWeakReferenceM
{
  public static void main(String[] args)
  {
    int iCount = 100000;
    /**
     * 当iCount取10万时,程序正常,references[100].get()为null,因为当heap内存不够是SoftReference对象自动被回收了,
     * 这里显然references[100]的软引用对象被回收了
     * 但,当iCount取100万时,
     * 程序也报异常:OutOfMemoryError: Java heap space
     * 这里是因为references数组太大了,而每一个references元素是一个SoftReference<Bean>对象,这个是强引用,不能释放
     */
    Reference<Bean>[] references = new WeakReference[iCount];//不能创建泛型数组,所以new SoftReference<Bean>[iCount];//错误
    for(int i=0;i<iCount;i++)
    {
      references[i] = new WeakReference<Bean>(new Bean("Jack_" + i,i));
    }
    System.out.println(references[100].get());
    
  }
}

 

d:虚引用

package test.reference;

import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;


/**
 * 虚引用有以下特征:
 * 虚引用永远无法使用 get() 方法取得对象的强引用从而访问目标对象。
 * 虚引用所指向的对象在被系统内存回收前,虚引用自身会被放入 ReferenceQueue 对象中从而跟踪对象垃圾回收。
 * 虚引用不会根据内存情况自动回收目标对象。
 * 另外值得注意的是,其实 SoftReference, WeakReference 以及 PhantomReference 的构造函数都可以接收一个 ReferenceQueue 对象。
 * 当 SoftReference 以及 WeakReference 被清空的同时,也就是 Java 垃圾回收器准备对它们所指向的对象进行回收时,
 * 调用对象的 finalize() 方法之前,它们自身会被加入到这个 ReferenceQueue 对象中,
 * 此时可以通过 ReferenceQueue 的 poll() 方法取到它们。
 * 而 PhantomReference 只有当 Java 垃圾回收器对其所指向的对象真正进行回收时,
 * 会将其加入到这个 ReferenceQueue 对象中,这样就可以追综对象的销毁情况。
 * 
 * 总结:PhantomReference 类似强引用,它不会自动根据内存情况自动对目标对象回收,
 * 所以这里在 Heap 里不断开辟新空间,当达到 5m 阈值时,系统报出 OutOfMemoryError 异常。
 * Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
 *
 */
public class TestPhantomReferenceM
{
  public static void main(String[] args)
  {
    ReferenceQueue<Bean> refQueue = new ReferenceQueue<Bean> ();
    int iCount = 100000;
    PhantomReference<Bean>[] referents  = new PhantomReference[iCount];
    for(int i=0;i<iCount;i++)
    {
      referents[i] = new PhantomReference<Bean>(new Bean("Jack_"+i,i),refQueue);
    }
    
  }
}

 

 

 

 

参考 

深入探讨 java.lang.ref 包 http://www.ibm.com/developerworks/cn/java/j-lo-langref/

分享到:
评论

相关推荐

    maven-resources-production java.lang.NegativeArraySizeException

    maven-resources-production java.lang.NegativeArraySizeException java.lang.NegativeArraySizeException 问题解决

    java错误处理:java.lang.OutOfMemoryError: Java heap space

    其中,“java.lang.OutOfMemoryError: Java heap space”是一种常见的异常情况,它表明Java虚拟机(JVM)的堆内存空间已耗尽。 #### 标题和描述中的知识点详解 **标题:“java错误处理:java.lang.OutOfMemoryError:...

    java.lang.OutOfMemoryError: Java heap space 解决方法

    "Java.lang.OutOfMemoryError: Java heap space 解决...Java.lang.OutOfMemoryError: Java heap space 是一种常见的 Java 错误,解决该问题需要从多方面入手,包括调整 JVM 的堆大小、调整 Tomcat 的配置、优化程序等。

    java.lang.OutOfMemoryError处理错误

    java.lang.OutOfMemoryError是Java虚拟机(JVM)中的一种常见错误,发生这种错误时,JVM将无法继续运行,程序将崩溃。这种错误的出现通常是由于Jvm的内存不足或内存泄露导致的。 出现java.lang.OutOfMemoryError的...

    idea启动项目报错 java.lang.NegativeArraySizeException解决方法

    idea启动项目报错 java.lang.NegativeArraySizeException解决方法

    java解决nested exception is java.lang.OutOfMemoryError Java heap space

    Java程序在运行过程中可能会遇到各种异常,其中"nested exception is java.lang.OutOfMemoryError: Java heap space"是一个常见的问题,通常发生在程序试图分配超过堆内存限制的空间时。这个错误表明Java虚拟机(JVM...

    解决axis2-CodegenWizardPluginBUG- java.lang.reflect.InvocationTargetException

    标题中的“解决axis2-CodegenWizardPluginBUG- java.lang.reflect.InvocationTargetException”指的是在使用Apache Axis2的CodegenWizardPlugin工具时遇到的一个错误。这个工具是Axis2框架的一部分,用于自动生成...

    java.lang.ClassNotFoundException异常的解决1

    2. **手动添加依赖**:在Java 9及以上版本中,你需要单独引入JAXB API及相关库的JAR包。这包括`javax.activation-1.2.0.jar`,`jaxb-api-2.3.0.jar`,`jaxb-core-2.3.0.jar`和`jaxb-impl-2.3.0.jar`。你可以在Maven...

    java.lang.runtimeexception unexpected subelement

    在Java编程中,`java.lang.RuntimeException` 是一个非检查异常(unchecked exception),它表示程序运行时出现的不正常情况。通常,这类异常是由于程序员的错误或代码逻辑的疏忽造成的,例如类型转换错误、空指针...

    org.apache.commons.lang jar包下载(commons-lang3-3.1.jar)

    commons-lang3.3.1.jar、Apache Commons包中的一个,包含了一些数据类型工具类,是java.lang.*的扩展。必须使用的jar包。为JRE5.0+的更好的版本所提供 Jar文件包含的类: META-INF/MANIFEST.MFMETA-INF/LICENSE....

    如何解决java.lang.StackOverflowError

    在Java编程中,`java.lang.StackOverflowError` 是一个常见的运行时异常,它通常发生在程序执行过程中,当Java虚拟机(JVM)的调用栈溢出时。调用栈是每个线程用来存储方法调用信息的数据结构,当递归调用过深或者...

    (最终解决)java.lang.UnsatisfiedLinkError解决尝试

    Java中的`java.lang.UnsatisfiedLinkError`是一个常见的运行时异常,通常出现在Java试图加载本地(C或C++)库但找不到相应的库文件时。这个错误可能是由于多种原因引起的,如库路径设置不正确、库文件不存在或者版本...

    编译时出现java.lang.OutOfMemoryError Java heap space异常

    ### 编译时出现java.lang.OutOfMemoryError Java heap space异常 #### 一、问题概述 在进行Java项目编译的过程中,可能会遇到`java.lang.OutOfMemoryError: Java heap space`这种异常。这类异常通常表明Java虚拟机...

    Java.lang.reflect 包下常用的类及方法简介

    在Java编程语言中,`java.lang.reflect`包是核心库的一部分,它提供了运行时访问类、接口、字段和方法的能力。这个包对于理解和操作对象的动态特性至关重要,尤其是在实现反射机制时。反射允许我们在程序运行期间...

    java.lang包介绍

    Java编程语言的基础构建块之一是`java.lang`包,它被自动导入到每个Java程序中,无需显式导入。这个包包含了许多核心类和接口,是编写任何Java应用程序不可或缺的部分。`java.lang`包中最基本的类是`Object`,它是...

    java.lang.OutOfMemoryError解决办法

    Java中的`java.lang.OutOfMemoryError`是一种常见的运行时错误,通常表示应用程序在尝试分配内存时遇到了问题。根据提供的信息,这个错误主要涉及到两个方面:`PermGen space`和`Java heap`,并且与Tomcat服务器相关...

Global site tag (gtag.js) - Google Analytics