内存泄露:程序运行过程中,会不断分配内存空间,那些不再使用的内存空间应该即时回收它们,从而保证系统可以再次使用这些内存,如果存在无用的内存没有被回收回来,这就是内存泄漏.
(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引用的作用与普通强引用效果完成一样。
如果将上面的SoftReference数组的长度改为100000,将修改运行上面的程序的命令如下
效果如下
从上图如可以看出,当使用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对象,这将使得程序因为系统内存不足而中止。运行上面程序,看到如下所示的错务(强引用导致的内存不足)
从上图不难看出,当程序使用强引用时,无论系统堆内存如何紧张,JVM垃圾回收机制都不会回收被强引用所引用的Java对象,因此最后导致程序因内存不足而中止。但如果把强引用改为软引用,就完成可以避免这种情况,这就是软引用的优势所在.
转自:http://hi.baidu.com/javabbs/blog/item/6286a4fb1148cf2f4f4aea8d.html
分享到:
相关推荐
Java中的GC(垃圾回收)是什么?如何手动触发对象的垃圾回收? 什么是Java中的设计模式?列举一些常见的设计模式。 什么是Java中的单例模式?如何实现线程安全的单例模式? 什么是Java中的生命周期回调方法?列举...
├─4.05 java细腻及讲解-jvm虚拟机常识-常用垃圾回收算法.mp4 ├─4.06 jvm运维实用排障工具.mp4 ├─4.07 jvm运维实用排障工具-jps-jstack.mp4 ├─4.08 jvm运维实用排障工具-jinfo-jstat.mp4 ├─4.09 jvm运维...
* 系统地学习 JVM 内存结构,垃圾回收、字节码与类加载技术。 * 在内存结构章节,能够学习掌握 JVM内存溢出现象,堆栈内存结构,利用内存诊断工具排查问题。彻底分析 StringTable的相关知识与性能优化,掌握直接内存...
面试高频算法、akka、多线程、NIO...自动内存管理(垃圾回收): Java具有自动内存管理机制,通过垃圾回收器自动回收不再使用的对象,使得开发者不需要手动管理内存,减轻了程序员的负担,同时也减少了内存泄漏的风险。
JVM内存回收最全的手册书籍,详细介绍了各种内存回收算法,是Java程序员进阶的必备书籍
包括:,Java基础及进阶书籍,...自动内存管理(垃圾回收): Java具有自动内存管理机制,通过垃圾回收器自动回收不再使用的对象,使得开发者不需要手动管理内存,减轻了程序员的负担,同时也减少了内存泄漏的风险。
│ 开篇词 Java 性能优化,是进阶高级架构师的炼金石.mp4 │ 02 理论分析:性能优化有章可循,谈谈常用的切入点.mp4 │ 03 深入剖析:哪些资源,容易成为瓶颈?.mp4 │ 04 工具实践:如何获取代码性能数据?....
二、Java进阶知识 集合框架:熟悉Java集合框架中的List、Set、Map等接口及其实现类,如ArrayList、HashSet、HashMap等。 泛型:理解泛型的概念及其在Java中的应用,如泛型类和泛型方法。 并发编程:了解Java中的...
java8 集合源码分析 Java架构师--成神之路 修改记录 版本 编写时间 作者 描述 v1.0.0 2019-10-29 Rock.Sang 梳理大纲 v1.0.1 2019-11-15 Rock.Sang 完善所有目录结构 v1.0.2 2020-01-07 Rock.Sang 添加英语模块 v...
01 理论分析:性能优化,有哪些衡量指标?需要注意什么?.mp4 02 理论分析:性能优化有章可循,...17 高级进阶:JVM如何完成垃圾回收?.mp4 18 高级进阶:JIT如何影响JVM的性能?.mp4 19 高级进阶:JVM常见优化参数.mp4
内存回收 & 状态机 JVM 类加载机制 垃圾回收算法对比 JVM 内存区域,开线程影响哪块区域内存? [对 Dalvik、ART 虚拟机有什么了解?对比?]( 虚拟机对比.md) 垃圾回收机制和调用 System.gc()的区别? 谈谈对 java ...
Java是一种高性能、跨平台的面向...自动内存管理(垃圾回收): Java具有自动内存管理机制,通过垃圾回收器自动回收不再使用的对象,使得开发者不需要手动管理内存,减轻了程序员的负担,同时也减少了内存泄漏的风险。
36.二手手机回收平台系统|基于JSP技术+ Mysql+Java+ B/S结构的二手手机回收平台系统设计与实现(可运行源码+数据库+设计文档) 二手手机回收平台系统的主要使用者分为管理员;个人中心、用户管理、手机品牌管理、手机...
健壮性与高性能:Java通过垃圾回收机制确保内存的有效管理,同时也能通过JIT编译器优化来提升运行时性能。 标准库丰富:Java拥有庞大的类库,如Java SE(Java Standard Edition)包含基础API,用于开发通用应用...
【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或...
【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或...
【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或...