`
robinjoe
  • 浏览: 45648 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

【转】Java高级进阶学习-Java的内存回收(2)

阅读更多

  内存泄露:程序运行过程中,会不断分配内存空间,那些不再使用的内存空间应该即时回收它们,从而保证系统可以再次使用这些内存,如果存在无用的内存没有被回收回来,这就是内存泄漏.
(1)强引用
  这是java程序中最常见的引用方式,程序创建一个对象,并把这个对象赋给一个引用变量(变量指向对象所占空间地址的首地址--转者注),这个引用变量就是强引用.java程序可通过强引用来访问实际的对象。当一个对象被一个或一个以上的强引用变量引用时,它处于可达状态,它不可能被系统垃圾回收机制回收。
  强引用是Java编程中广泛使用的引用类型,被强引用所引用的Java对象绝不会被垃圾回收机制回收,即使系统内存紧张;即使有些Java对象以后永远也不会被用到,JVM也不会回收被强引用所引用的Java对象.
  由于JVM肯定不会回收强引用所引用的JAVA对象,因此强引用是造成JAVA内存泄漏的主要原因。
    如 ReceiptBean rb=new ReceiptBean(); rb就代表了一种强引用的方式
(2)软引用
  软引用需要通过SoftReference类来实现,当一个对象只具有软引用时,它可能被垃圾回收机制回收。对于只有软引用的对象而言,当系统内存空间足够时,它不会被系统回收,程序也可以使用该对象;当系统内存空间不足时,系统将回收它.
  软引用通常用在对内存敏感的程序中,软引用是强引用很好的替代。对于软引用,当系统内存空间充足时,软引用与强引用没有太大的区别,当系统内存空间不足时,被软引用所引用的JAVA对象可以被垃圾回收机制回收,从而避免系统内存不足的异常.
  当程序需要大量创建某个类的新对象,而且有可能重新访问已创建老对象时,可以充分使用软引用来解决内存紧张的问题。
例如需要访问1000个Person对象,可以有两种方式
方法一 依次创建1000个对象,但只有一个Person引用指向最后一个Person对象
方法二 定义一个长度为1000个的Person数组,每个数组元素引用一个Person对象.

对于方法一,弱点很明显,程序不允许需要重新访问前面创建的Person对象,即使这个对象所占的空间还没有被回收。但已经失去了这个对象的引用,因此也不得不重新创建一个新的Person对象(重新分配内存),而那个已有的Person对象(完整的,正确的,可用的)则只能等待垃圾回收
对于方法二,优势是可以随时重新访问前面创建的每个Person对象,但弱点也有,如果系统堆内存空间紧张,而1000个Person对象都被强引用引着,垃圾回收机制也不可能回收它们的堆内存空间,系统性能将变成非常差,甚至因此内存不足导致程序中止。

  如果用软引用则是一种较好的方案,当堆内存空间足够时,垃圾回收机制不会回收Person对象,可以随时重新访问一个已有的Person对象,这和普通的强引用没有任何区别。但当heap堆内存空间不足时,系统也可以回收软引用引用的Person对象,从而提高程序运行性能,避免垃圾回收.

  例如.下面程序创建一个SoftReference数组,通过SoftReference数组来保存100个对象,当系统内存充足时,SoftRference引用和强引用并没在太大的区别

class Person
{
String name;
int age;
public Person(String name , int age)
{
this.name = name;
this.age = age;
}
public String toString()
{
return "Person[name=" + name
+ ", age=" + age + "]";
}
}
public class SoftReferenceTest
{
public static void main(String[] args)
throws Exception
{
SoftReference<Person>[] people =
new SoftReference[100];
for (int i = 0 ; i < people.length ; i++)
{
people[i] = new SoftReference<Person>(new Person(
"名字" + i , (i + 1) * 4 % 100));
}
System.out.println(people[2].get());
System.out.println(people[4].get());
//通知系统进行垃圾回收
System.gc();
System.runFinalization();

/*转者注--后续会补充查找二者不同的详细资料

*System.gc(),运行垃圾回收机制
*System.runFinalization(),调用Finalize()释放资源

*/
//垃圾回收机制运行之后,SoftReference数组里的元素保持不变
System.out.println(people[2].get());
System.out.println(people[4].get());
}
}


  上面程序创建了一个长度为100的SoftReference数组,程序使用这个数组来保存100个Person对象,当系统内存足够时,如下面图示,即使系统进行垃圾回收,垃圾回收机制也不会回收这些Person对象所占用的内存空间。这种情况下,SoftReference引用的作用与普通强引用效果完成一样。

 

Java高级进阶学习-Java的内存回收(2)


如果将上面的SoftReference数组的长度改为100000,将修改运行上面的程序的命令如下
效果如下

 

Java高级进阶学习-Java的内存回收(2)


  从上图如可以看出,当使用java -Xmx2m -Xms2m SoftReferenceTest命令强制堆内存只有2m,而且程序创建一个长度为100000的数组,这样使得系统内存紧张。在这种情况下,软引用所引用的Java对象将会被垃圾回收。

下面,我们再来对比一下强引用的程序,将上面程序修改如下
public class StrongReferenceTest
{
public static void main(String[] args)
throws Exception
{
Person[] people =
new Person[100000];
for (int i = 0 ; i < people.length ; i++)
{
people[i] = new Person(
"名字" + i , (i + 1) * 4 % 100);
}
System.out.println(people[2]);
System.out.println(people[4]);
//通知系统进行垃圾回收
System.gc();
System.runFinalization();
//StrongReference数组里不受任何影响
System.out.println(people[2]);
System.out.println(people[4]);
}
}

  上面程序以传统方式创建了一个Person数组,该数组长度为100000,即程序的堆内存将保存100000个Person对象,这将使得程序因为系统内存不足而中止。运行上面程序,看到如下所示的错务(强引用导致的内存不足)

Java高级进阶学习-Java的内存回收(2)


  从上图不难看出,当程序使用强引用时,无论系统堆内存如何紧张,JVM垃圾回收机制都不会回收被强引用所引用的Java对象,因此最后导致程序因内存不足而中止。但如果把强引用改为软引用,就完成可以避免这种情况,这就是软引用的优势所在.


转自:http://hi.baidu.com/javabbs/blog/item/6286a4fb1148cf2f4f4aea8d.html

分享到:
评论

相关推荐

    Java语言程序设计-进阶篇-原书第8版

    以下是一些Java进阶编程中常见的知识点: 1. 面向对象的高级特性:包括继承、封装、多态的深入理解,以及抽象类和接口的使用,泛型编程,注解以及反射机制。 2. Java集合框架:深入学习List、Set、Map等集合接口的...

    重塑java基础高级进阶资源分享

    根据提供的文件信息,我们可以推断出这是一份关于Java编程语言高级进阶的学习资源分享。虽然分享者在描述中提到“仅仅是分享!实在没有c币可以留言我,我可以私发”,这里的“c币”可能是指某个社区或平台内的虚拟...

    java高级进阶知识

    2. **垃圾回收机制**:Java的自动内存管理依赖于垃圾回收,包括新生代GC、老年代GC、全停顿GC等策略。理解这些机制有助于我们优化内存使用,减少垃圾回收带来的性能影响。 3. **类加载机制**:JVM的类加载过程包括...

    java经典面试题目-面经-java-Java语言的进阶概念-常用的库和框架-并发编程-网络编程-Web开发-面经

    Java的垃圾回收(GC)自动管理内存,回收不再使用的对象所占用的空间。手动触发GC可以通过`System.gc()`,但不推荐,因为GC策略由JVM管理,频繁调用可能导致性能下降。 设计模式是解决软件设计中常见问题的模板,如...

    Java进阶学习资料.zip

    在Java进阶学习中,你需要掌握以下几个关键的知识点: 1. 高级数据结构与算法:理解并能熟练运用ArrayList、LinkedList、HashMap等集合框架,深入研究Set、Queue、Stack等接口及其实现类。同时,学习并应用高级排序...

    Java高级进阶面试题目.pdf

    标题“Java高级进阶面试题目.pdf”表明这是一份涵盖Java高级技术点的面试题资料,它适用于那些寻求在Java领域深入发展的求职者或者技术提升者。描述中的“Java高级进阶面试题目”进一步细化了这份资料的定位,即为...

    java 高级架构进阶学习

    ### Java高级架构进阶学习知识点概述 #### 一、思维导图 - **知识点概览**:思维导图是理解Java高级架构的关键工具之一。它能够帮助开发者快速掌握架构设计的核心概念和技术要点。 - **核心内容**: - **基础知识...

    Java面向对象(进阶)- Object类的详细概述

    在Java编程语言中,面向对象是其核心特性之一。Object类是所有Java类的根父类,无论何时我们创建一个新的类,除非明确指定其他父类,否则它都会默认继承Object类。这使得Object类中的方法对所有Java类都可用,体现了...

    java大神进阶之路.pdf

    Java大神进阶之路是一份针对Java开发者进阶提升的学习指南,详细描述了从编程基础到Java语言本身的精通,再到数据库以及Java Web核心技术的掌握,以及每个阶段所需要学习和掌握的知识点。文中特别强调了数据结构和...

    java学习资料-免费-适合0基础&进阶学习

    2. **进阶Java技术**: - **集合框架**:深入学习ArrayList、LinkedList、HashSet、HashMap等数据结构的实现和应用场景。 - **多线程**:了解并发编程,包括线程的创建、同步机制(如synchronized关键字、Lock接口...

    1 Java 程序员进阶之路(暗黑版)1

    【Java程序员进阶之路(暗黑版)1】是一篇专为Java爱好者设计的进阶教程,旨在通过详细且通俗易懂的方式,帮助读者提升Java...本专栏通过实例和故事化的讲解,使得学习过程更加生动有趣,是进阶Java程序员的理想资源。

    java2进阶教程

    Java 2 进阶教程是针对已经掌握Java基础的开发者设计的一系列深入学习材料,旨在帮助他们提升在Java编程领域的专业技能。这个教程可能涵盖了诸如多线程、网络编程、IO流、集合框架、异常处理、反射机制、设计模式、...

    java进阶提高学习教程-13JVM与多线程.pptx

    Java进阶学习教程中的第13章主要涵盖了JVM(Java虚拟机)和多线程两个核心概念。JVM是Java程序运行的基础,它负责解释执行字节码文件,并提供了Java语言的跨平台特性。Java程序通过JVM与操作系统交互,使得程序可以...

    Java语言程序设计-进阶篇(原书第8版)

    《Java语言程序设计-进阶篇》是Java编程学习的重要参考资料,尤其对于已经掌握Java基础知识的开发者来说,这本书是进一步提升技能的关键。该书的第八版涵盖了Java编程的诸多高级主题,旨在帮助读者深入理解Java的...

    Java语言程序设计-进阶篇(原书第10版 中英文)

    一、Java进阶核心概念 1. 面向对象编程:Java是一种纯面向对象的语言,进阶篇会深入讲解类、对象、封装、继承、多态等面向对象的基本概念和应用。通过理解和掌握这些概念,读者可以更好地设计和实现复杂的软件系统...

    2021 Java架构进阶 Nginx企业级教程.txt打包整理.zip

    标题"2021 Java架构进阶 Nginx企业级教程.txt打包整理.zip"表明这是一个关于Java架构进阶和Nginx企业级应用的教程集合,内容可能涵盖Java技术栈的高级应用、系统架构设计以及Nginx服务器的配置和优化。.txt格式的...

    Java语言程序设计-进阶篇(原书第10版).pdf

    《Java语言程序设计-进阶篇》是针对已经掌握Java编程基础的学习者提供的一本深入学习书籍,尤其适合想要提升编程技巧和理解高级特性的读者。这本书基于原书的第10版,意味着它涵盖了最新的Java版本特性,比如Java 8...

    java程序设计进阶版

    《Java程序设计进阶版》原书第10版是一本深入探讨Java编程技术的权威著作,适合已经掌握基础Java知识的学习者进一步提升技能。这本书以其高清晰度和完整的章节结构,为读者提供了丰富的学习资源,是Java程序员进阶...

    Java进阶.zip

    "Java进阶"这个主题涵盖了Java开发中的高级概念和技术,旨在帮助程序员深入理解Java的精髓,提升开发技能。SunJava.pdf可能包含的是由Sun Microsystems(Java的原始开发者)发布的官方文档或教程。 1. **内存管理与...

    Java语言程序设计-基础篇-进阶篇源码

    本资源包含了“Java语言程序设计-基础篇”和“Java语言程序设计-进阶篇”的全部源码,是学习和深入理解Java编程的理想资料。 在基础篇中,主要涵盖了以下知识点: 1. **Java简介**:Java的历史、特性,以及为什么...

Global site tag (gtag.js) - Google Analytics