文档章节

再谈java的内存泄露

乱蓬头
 乱蓬头
发布于 2017/05/18 13:20
字数 1060
阅读 1
收藏 0

摘要: 这两天看了一本老书《bitter java》,第一次系统地了解了所谓“反模式”。就书的内容来说已经过于陈旧,书中提到的magic servlet、复合jsp等等反模式已经是早就熟知的编程禁忌,而如web页面不能有太多元素这样的反模式也因为ajax的出现(异步加载)变的不是那么“反模式”了,其中又讲述了很多ejb的反模式,这些在轻量级框架流行的今天也早已经过时。

这两天看了一本老书《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

本文转载自:http://click.aliyun.com/m/21362/

共有 人打赏支持
乱蓬头
粉丝 0
博文 382
码字总数 2595
作品 0
私信 提问
在 JNI 编程中避免内存泄漏

此文转自 IBM developerWorks JNI 编程简介 JNI,Java Native Interface,是 native code 的编程接口。JNI 使 Java 代码程序可以与 native code 交互——在 Java 程序中调用 native code;在...

IBMdW
2011/04/26
968
1
ThreadLocal可能引起的内存泄露

  threadlocal里面使用了一个存在弱引用的map,当释放掉threadlocal的强引用以后,map里面的value却没有被回收.而这块value永远不会被访问到了. 所以存在着内存泄露. 最好的做法是将调用thr...

天天顺利
06/15
0
0
out就可以理解为System类的静态成员变量引用了PrintStream类的对象

面试题是实验室师兄面试提供的。两道题 题1:Java中System.out.print()如何理解? 查阅API文档,我们可以知道:System是Java中的一个类,而out是System类的成员 。 out属于java.io.PrintStre...

变小火
06/29
0
0
多线程并发神器--ThreadLocal

什么是ThreadLocal 可以理解成线程本地变量,传统的线程对一个变量操作时操作的是同一个对象,也存在线程安全的问题。 ThreadLocal是一个变量的本地副本,线程对变量的操作不会影响其他线程。...

java技术栈
2017/08/13
0
0
Java并发编程之ThreadLocal内存泄漏探究

使用 ThreadLocal 不当可能会导致内存泄露,是什么原因导致的内存泄漏呢? 我们首先看一个例子,代码如下: / Created by cong on 2018/7/14. */public class ThreadLocalOutOfMemoryTest { ...

狂小白
07/14
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Flink-数据流编程模型

1、抽象等级 Flink提供了不同级别的抽象来开发流/批处理应用程序。 1) 低层级的抽象 最低层次的抽象仅仅提供有状态流。它通过Process函数嵌入到DataStream API中。它允许用户自由地处理来自一...

liwei2000
23分钟前
1
0
Java开发Swing实战JFrame和JTabbedPane容器的用法详细解析

概述: 项目是一个桌面程序,涉及标签和按钮组件、布局管理器组件、面板组件、列表框和下拉框组件等组件,以及Swing事件处理机制。 下面先从最基础的界面开始。 /** * @author: lishuai * @...

金铭鼎IT教育
28分钟前
9
0
flask 之旅

环境 为了正确地跑起来,你的应用需要依赖许多不同的软件。 就算是再怎么否认这一点的人,也无法否认至少需要依赖Flask本身。 你的应用的运行环境,在当你想要让它跑起来时,是至关重要的。 ...

hblt-j
28分钟前
6
0
easyui的上传文件

记录一下自己亲手操刀easyui的心得:不用不知道,一用就问题多,网上查资料,有用的真的太少了 ——————————————————正文 FileBox,还是不错的讲真,至少我去自己写就gaga了...

anlve
29分钟前
4
0
如何做好SQLite 使用质量检测,让事故消灭在摇篮里

本文由云+社区发表 SQLite 在移动端开发中广泛使用,其使用质量直接影响到产品的体验。 常见的 SQLite 质量监控一般都是依赖上线后反馈的机制,比如耗时监控或者用户反馈。这种方式问题是: ...

腾讯云加社区
32分钟前
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部