内存泄露 Memory Leaks
什么是内存泄露
内存管理一直是Java 所鼓吹的强大优点。开发者只需要简单地创建对象,而Java的垃圾收集器将会自动管理内存空间的分配和释放。但在很多情况下,事情并不那么简单,在 Java程序中总是会频繁地发生内存泄露(Memory Leaks)。内存泄露的定义: 当某些对象不再被应用程序所使用,但是由于仍然被引用而导致垃圾收集器不能释放他们。用白话来说就是: 该回收的内存没被回收,最后因为内存不够用而导致程序报错。要理解这个定义,我们需要理解内存中的对象状态。 下图展示了什么是不使用的部分,以及未被引用的部分。从图中可以看出,内存中存在着"有引用的对象"和"无引用的对象"。 无引用的对象将被垃圾收集器所回收,而有引用的对象则不会被当做垃圾收集。因为没有任何其他对象所引用,所以无引用对象一定是不再使用的,但是有一部分无用对象仍然被(无意中)引用着。这就是发生内存泄露的根源。
为什么会发生内存泄露
为什么内存会泄露?让我们看下面的实例来了解为什么内存会泄露。在下面的情境中,对象A引用了对象B。 A的生命周期(t1 - t4) 比 B的(t2 - t3)要长得多。 当对象B在应用程序逻辑中不会再被使用以后, 对象 A 仍然持有着 B的引用。 (根据虚拟机规范)在这种情况下垃圾收集器不能将 B 从内存中释放,这种情况很可能会引起内存问题。甚至有可能 B 也持有一大堆其他对象的引用,这些对象由于被 B 所引用,也不会被垃圾收集器所回收。所有这些无用的对象将消耗大量宝贵的内存空间。
发生内存泄漏的常见场景
- 静态集合类
像HashMap、ArrayList等的使用最容易出现内存泄露,由于静态变量的生命周期和应用程序一致,所以他们所引用的所有的对象也不能被释放。如public class Test {static ArrayList<Person> list = new ArrayList<Person>();//list中引用的对象在应用整个生命周期中都不会被释放public static void main(String[] args) {for (int i = 1; i < 10; i++) {Person person = new Person("" + i);list.add(person);person = null;//将变量person指向null,而不是指向堆内存中的Person对象;注意这时堆内存中的Person对象并没有被回收}for (Person person : list) {System.out.println(person);//所有Person对象都没有被回收}}}class Person {public String name;public Person(String name) {this.name = name;}@Overridepublic String toString() {return name;}}在这个例子中,如果仅仅释放引用本身(person = null),那么集合仍然引用该对象,所以这个对象对GC 来说是不可回收的。因此,如果对象加入到集合后,还必须从集合中删除,最简单的方法就是将集合对象设置为null。
- 监听器、回调、外部模块的引用
当注册的监听器不再使用后,如果没有被注销,那么很可能会发生内存泄露。public class Test {public static void main(String[] args) {B b = new B();A a = new A();b.register(a);a = null;//虽然讲监听器设为null,但是监听器对象A并没有被回收,因为它被B引用了b.show();//监听器工作了b.unregister();//用完要注销掉}}interface Listener {public void listen();}class A implements Listener {@Overridepublic void listen() {System.out.println("监听器工作了");}}class B {Listener listener;public void register(Listener listener) {//B持有了Listener的引用,除非在B内部将其设为null,否则listener将不会被回收this.listener = listener;}public void unregister() {listener = null;}public void show() {if (listener != null) listener.listen();}}
- 各种连接
比如数据库连接、网络连接(socket)和io流的连接,除非显式的调用了其close()方法将其连接关闭,否则是不会自动被GC回收的。
- 内部类的引用
内部类的引用是比较容易遗忘的一种,而且一旦没释放可能导致一系列的后继类对象没有释放。
- 单例模式
单例对象在被初始化后将在JVM的整个生命周期中存在(以静态变量的方式),如果单例对象持有外部对象的引用,那么这个外部对象将不能被jvm正常回收,导致内存泄露。
内存泄露 Memory Leaks的更多相关文章
- SQL Server 内存泄露(memory leak)——游标导致的内存问题
原文:SQL Server 内存泄露(memory leak)--游标导致的内存问题 转自:http://blogs.msdn.com/b/apgcdsd/archive/2011/07/01/sql ...
- 内存泄漏 Memory Leaks 内存优化 MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
- 内存溢出(Oom)和内存泄露(Memory leak)
1.概念 内存溢出(Oom):1.内存不够用:2.数据长度短的数据类型存储了一个数据长度较大的数据类型:3.一个结果 内存泄露(Memory leak):1.忘记释放已用内存,内存管理较为常见的现象: ...
- 利用linux的mtrace命令定位内存泄露(Memory Leak)
一谈到内存泄露, 多数程序猿都闻之色变. 没错, 内存泄露非常easy引入. 但非常难定位. 以你我的手机为例(如果不常常关机). 如果每天泄露一些内存, 那么開始的一个星期, 你会发现手机好好的. ...
- 内存溢出(Memory Overflow)和内存泄露(Memory Leak)的区别
内存泄漏指你用malloc或new申请了一块内存,但是没有通过free或delete将内存释放,导致这块内存一直处于占用状态 内存溢出指你申请了10个字节的空间,但是你在这个空间写入11或以上字节的数 ...
- 使用JProfiler分析定位java内存泄露memory leak
使用jprofiler远程profile JBoss应用服务器 项目中发现JBoss出现内存泄露, 从2G一直涨到3.5G左右 开始考虑使用jmap dump出内存来, 在用jhap打开浏览器分析. ...
- python内存泄露memory leak排查记录
问题描述 A服务,是一个检测MGR集群主节点是否发生变化的服务,使用python语言实现的. 针对每个集群,主线程会创建一个子线程,并由子线程去检测.子线程会频繁的创建和销毁. 上线以后,由于经常会有 ...
- Java 基础 - 内存泄露Memory leak & 内存溢出Out of memory
内存泄露 & 内存溢出 关系 https://www.cnblogs.com/panxuejun/p/5883044.html 内存泄露的6种情况: https://blog.csdn.net ...
- 内存泄露 memory leak 的原因
#include <iostream> using namespace std; void foo() { MyClass *x; x = new MyClass(); //指向的丢失了 ...
随机推荐
- Ipad亚麻布纹背景-最终效果_学习教程
- 绘图时,根据size()和自定义rect编程的区别
在绘图的时候,很多时候编写的代码需要根据当前窗口自身的size来进行绘制,这个时候可以添加一个额外的中间rect来做过度,这样以后的绘图机制不会 随着size的变化而不断变化.你的处理逻辑可以保持不变 ...
- 142 Linked List Cycle II(如果链表有环,找到入口结点Medium)
题目意思:如果有环,返回入口结点 思路:先判断有没环,再计算环的结点数,然后p1指向头,p2往后移结点次数,p1.p2相遇为入口结点 ps:还是利用指针间距这个思路 /** * Definition ...
- php 手机电话正则表达式验证
function check_telnum1($telnum) { $b1 = (preg_match(" ...
- Activity完整的生命周期
首语:群里看到一位网友说:你能说出Activity的完整生命周期吗?看到这句话,我也在反思自己,我也是个fresh,所以想找个时间仔细的扒一扒Activity生命周期. 首先拿一张简单而又复杂的生命周 ...
- UILabel的size根据文字的长短变化
UILabel *label = [[UILabel alloc] init]; label.backgroundColor = [UIColor blackColor]; [self.view a ...
- Hazelcase 简介
原博客地址:http://blog.csdn.net/zhu_tianwei/article/details/47984599 Hazelcast是一种内存数据网格in-memory data gri ...
- 百度地图LBS云平台读写数据操作类
最近写了个叫<行踪记录仪>的手机软件,用了百度云来记录每个用户的最近位置,以便各用户能在地图上找到附近的人,为此写了个类来读写数据,大致如下: import java.util.Array ...
- 转:PHP - .htaccess设置显示PHP错误
使用.htaccess可以在某种程度上更改PHP的错误显示的设置,实际上,相当于更改PHP.ini的参数,很是方便. 将以下相应代码放到对应目录中的.htaccess文件,即可实现相应功能. 关闭错误 ...
- 百度统计js被劫持用来DDOS Github的JS注释
前几天在乌云看见了百度统计js被劫持用来DDOS Github,就想看看执行的核心JS是怎么样请求的. 就分析了下JS的执行,发现乌云解析的地方说错了. 文章里面说.大概功能就是关闭缓存后每隔2秒加载 ...

