Java中的内存泄露

一、概述

虽然Java有垃圾收集器帮助实现内存自动管理,虽然GC有效的处理了大部分内存,但是并不能完全保证内存的不泄露。

二、内存泄露

内存泄露就是堆内存中不再使用的对象,但是垃圾回收期无法从内存中删除他们的情况,因此他们会被不必要的一直存在。,这种情况会耗尽内存资源并降低系统性能,最终以OOM终止。

垃圾回收器会定期删除未引用的对象,但它永远不会收集那些仍在引用的对象。

内存泄露的症状:

    应用程序长时间连续运行时性能严重下降;

    应用程序中的OutOfMemoryError堆错误;

    自发且奇怪的应用程序崩溃;

    应用程序偶尔会耗尽连接对象。

三、Java中内存泄露类型

1、static字段引起的内存泄露

大量使用static字段会潜在的导致内存泄露,在Java中,静态字段通常拥有与整个应用程序相匹配的生命周期。

解决办法:最大限度的减少静态变量的使用;单例模式时,依赖于延迟加载对象而不是立即加载方式。

2、未关闭的资源导致内存泄露

每当创建连接或者打开流时,JVM都会为这些资源分配内存。如果没有关闭连接,会导致持续占有内存。在任意情况下,资源留下的开放连接都会消耗内存,如果我们不处理,就会降低性能,甚至OOM。

解决办法:使用finally块关闭资源;关闭资源的代码,不应该有异常;jdk1.7后,可以使用try-with-resource块。

3、不正确的equals()和hashCode()

在HashMap和HashSet这种集合中,常常用到equal()和hashCode()来比较对象,如果重写不合理,将会成为潜在的内存泄露问题。

解决办法:用最佳的方式重写equals()和hashCode。

4、引用了外部类的内部类

非静态内部内的初始化,总是需要外部类的实例;默认情况下,每个非静态内部类都包含对其包含内的隐式引用,如果我们在应用程序中使用这个内部类对象,那么即使在我们的包含类对象超出范围后,它也不会被垃圾收集。

解决办法:如果内部类不需要访问包含的类成员,考虑转换为静态类。

5、finalize()方法造成的内存泄露

重写finalize()方法时,该类的对象不会立即被垃圾收集器收集,如果finalize()方法的代码有问题,那么会潜在的引发OOM;

解决办法:避免重写finalize()。

6、常量字符串造成的内存泄露

如果我们读取一个很大的String对象,并调用了inter(),那么它将放到字符串池中,位于PermGen中,只要应用程序运行,该字符串就会保留,这就会占用内存,可能造成OOM。

解决办法:增加PermGen的大小,-XX:MaxPermSize=512m;升级Java版本,JDK1.7后字符串池转移到了堆中。

7、使用ThreadLocal造成内存泄露

使用ThreadLocal时,每个线程只要处于存货状态就可保留对其ThreadLocal变量副本的隐式调用,且将保留其自己的副本。使用不当,就会引起内存泄露。

一旦线程不在存在,ThreadLocals就应该被垃圾收集,而现在线程的创建都是使用线程池,线程池有线程重用的功能,因此线程就不会被垃圾回收器回收。所以使用到ThreadLocals来保留线程池中线程的变量副本时,ThreadLocals没有显示的删除时,就会一直保留在内存中,不会被垃圾回收。

解决办法:不在使用ThreadLocal时,调用remove()方法,该方法删除了此变量的当前线程值。不要使用ThreadLocal.set(null),它只是查找与当前线程关联的Map并将键值对设置为当前线程为null。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Java SE 基础: 封装、继承、多态 封装: 概念:就是把对象的属性和操作(或服务)结合为一个独立的整体,并尽...
    Jayden_Cao阅读 2,140评论 0 8
  • 内存泄露是指一个不再被程序使用的对象或变量还在内存中占有存储空间。 在C/C++中,内存分配与释放是由开发人员来负...
    小人物灌篮阅读 661评论 0 0
  • 在Java中,内存泄漏就是存在一些被分配的对象,这些对象有下面两个特点,首先,这些对象是可达的,即在有向图中,存在...
    Gracker阅读 971评论 1 7
  • [TOC] 1. ThreadLocal简介 网上看到一些文章,提到关于ThreadLocal可能引起的内存泄露,...
    sheen口开河阅读 20,644评论 1 26
  • 六年,说长不长,说短不短。六年,我们从陌生人到幸福的三口之家。想想这六年的时光里,有太多太多美好的回忆,我...
    娅妮妮阅读 155评论 4 3