再谈java的内存泄露

简介:

这两天看了一本老书《bitter java》,第一次系统地了解了所谓“反模式”。就书的内容来说已经过于陈旧,书中提到的magic servlet、复合jsp等等反模式已经是早就熟知的编程禁忌,而如web页面不能有太多元素这样的反模式也因为ajax的出现(异步加载)变的不是那么“反模式”了,其中又讲述了很多ejb的反模式,这些在轻量级框架流行的今天也早已经过时。不过书中有一个章节倒是挺有价值,讲述的是java的内存泄露问题,我认为是我目前读的关于这方面问题比较有价值的介绍。
    网上关于java内存泄露的资料都过于玄乎,其实java导致内存泄露的原因很明确:长生命周期的对象持有短生命周期对象的引用就很可能发生内存泄露,尽管短生命周期对象已经不再需要,但是因为长生命周期对象持有它的引用而导致不能被回收,这就是java中内存泄露的发生场景。作者在书中提到了3个场景:
1。流失监听器问题,在awt、swing编程中,给组件添加了事件监听器,这些组件的生命周期如果很长的话,监听器对象将不能被正确回收。关于GUI编程我不是很熟悉,这一点存有疑问,因为显然你触发一个按钮的事件,当然是一直期待同样的行为发生,如果删除了监听器或者使用弱引用让JVM回收不符合业务逻辑和用户体验。

2。集合类,集合类仅仅有添加元素的方法,而没有相应的删除机制,导致内存被占用。这一点其实也不明确,这个集合类如果仅仅是局部变量,根本不会造成内存泄露,在方法栈退出后就没有引用了会被jvm正常回收。而如果这个集合类是全局性的变量(比如类中的静态属性,全局性的map等),那么没有相应的删除机制,很可能导致集合所占用的内存只增不减,因此提供这样的删除机制或者定期清除策略非常必要。

3。单例模式。不正确使用单例模式是引起内存泄露的一个常见问题,单例对象在被初始化后将在JVM的整个生命周期中存在(以静态变量的方式),如果单例对象持有外部对象的引用,那么这个外部对象将不能被jvm正常回收,导致内存泄露,考虑下面的例子:
class A{
    public A(){
           B.getInstance().setA(this);
   }
   ....
}
//B类采用单例模式
class B{
     private A a;
     private static B instance=new B();
     public B(){}
     public static B getInstance(){
         return instance;
    }
    public void setA(A a){
          this.a=a;
    }
   //getter...
}

显然B采用singleton模式,他持有一个A对象的引用,而这个A类的对象将不能被回收。想象下如果A是个比较大的对象或者集合类型会发生什么情况。

    上面所讲的这些也启发我们如何去查找内存泄露问题,第一选择当然是利用工具,比如jprofiler,第二就是在代码复审的时候关注长生命周期对象:全局性的集合、单例模式的使用、类的static变量等等。

文章转自庄周梦蝶  ,原文发布时间 2007-11-11

目录
相关文章
|
5月前
|
监控 安全 Java
Java基础知识:解释一下Java虚拟机(JVM)是什么。
Java基础知识:解释一下Java虚拟机(JVM)是什么。
41 3
|
3月前
|
算法 Java 程序员
Java的垃圾回收机制及其优化方法
【2月更文挑战第7天】垃圾回收是Java语言中一项重要的特性,它可以自动管理内存资源,避免了手动释放内存的繁琐过程。本文将介绍Java的垃圾回收机制、垃圾回收算法以及优化方法,帮助读者更好地理解和应用Java的垃圾回收技术。
|
10月前
|
Oracle Java 关系型数据库
02-有哪些常见的JVM?请说下Java代码的运行机制
常见的JVM有Oracle JDK、OpenJDK、IBM JVM、Azul Zing JVM等。Java代码的运行机制如下:首先,Java源代码被编译成字节码文件(.class文件),其中包含了可执行指令。然后,JVM将字节码加载到内存中,进行校验、准备和解析等操作。接着,JVM将字节码转换为机器码,并交给处理器执行。执行过程中,JVM负责内存管理、垃圾回收和线程调度等任务。最后,程序执行完毕或遇到异常,JVM终止程序的运行。JVM的关键组件包括类加载器、即时编译器和垃圾回收器,它们确保了Java代码的可移植性、安全性和性能优化。这些信息有助于理解Java代码是如何在JVM上运行的。
79 0
02-有哪些常见的JVM?请说下Java代码的运行机制
|
存储 缓存 Java
Java - 深入理解Java中的逃逸分析
Java - 深入理解Java中的逃逸分析
123 0
|
安全 Java
JVM系列之:再谈java中的safepoint
JVM系列之:再谈java中的safepoint
JVM系列之:再谈java中的safepoint
|
Java Android开发
了解Java中的内存泄漏
1. 简介 Java的核心优势之一是在内置垃圾收集器(简称GC)的帮助下实现自动内存管理。GC隐含地负责分配和释放内存,因此能够处理大多数内存泄漏问题。
853 0
|
Java
Java 中会存在内存泄漏吗?
理论上Java因为有垃圾回收机制(GC)不会存在内存泄露问题(这也是Java被广泛使用于服务器端编程的一个重要原因);然而在实际开发中,可能会存在无用但可达的对象,这些对象不能被GC回收,因此也会导致内存泄露的发生。
956 0
|
Java 程序员 数据库连接
Java中的内存泄露的几种可能
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_34173549/article/details/81057259 Java内存泄漏引起的原因:   内存泄漏是指无用对象(不再使用的对象)持续占有内存或无用对象的内存得不到及时释放,从而造成内存空间的浪费称为内存泄漏。
941 0