文档章节

再谈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
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
Java并发编程笔记之ThreadLocal内存泄漏探究

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

狂小白
07/14
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

没有更多内容

加载失败,请刷新页面

加载更多

关于Excel表格导出方法--application/vnd.ms-excel

关于Excel表格导出方法--application/vnd.ms-excel 由于本人所做的项目中需要用到两种将JSP页面table导出到Excel表格的方法(老板也是坑爹),一种是在后台操作数据库来实现,比较简单。由于...

DemonsI
23分钟前
1
0
springboot配置读写分离

我不提供内容,我只是好文章的搬运工 https://www.cnblogs.com/wuyoucao/p/9610882.html

颖辉小居
26分钟前
1
0
Spring 传参

spring传参之@RequestParam注解 @RequestParam注解有三个参数分别是: value、 required、 defaultValue 代码: @RequestMapping(value="test1", method = RequestMethod.GET) public String......

休辞醉倒
28分钟前
1
0
go http 框架性能大幅下降原因分析

最近在开发一个web 框架,然后业务方使用过程中,跟我们说,压测qps 上不去,我就很纳闷,httprouter + net/http.httpserver , 性能不可能这么差啊,网上的压测结果都是10w qps 以上,几个m...

鼎铭
28分钟前
7
0
GCC编译过程记

GCC编译过程记 一、引言 对于编程工作者来说,GCC是一个熟悉的名字,它的全称是“GNU Compiler Collection”。GCC是一组编译器集合,目前其支持C、C++、Objective-C、Objective-C++、Go和RBI...

珲少
30分钟前
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部