简述Java内存泄露
翻译人员: 铁锚
翻译时间: 2013年11月4日
原文链接: The Introduction of Memory Leaks
内存管理一直是Java 所鼓吹的强大优点。开发者只需要简单地创建对象,而Java的垃圾收集器将会自动管理内存空间的分配和释放.但在很多情况下,事情并不那么简单,在 Java程序中总是会频繁地发生内存泄露(Memory Leaks).
本文阐述什么是内存泄露,为什么会泄露,以及如何防止内存泄露。
内存泄露是什么?
内存泄露的定义: 当某些对象不再被应用程序所使用,但是由于仍然被引用而导致垃圾收集器不能释放(Remove,移除)他们.
用白话来说就是: 该回收的内存没被回收,最后因为内存不够用而导致程序报错。
要理解这个定义,我们需要理解内存中的对象状态. 下图展示了什么是不使用的部分,以及未被引用的部分。
从图中可以看出,内存中存在着 有引用的对象,和无引用的对象. 无引用的对象将被垃圾收集器所回收,而有引用的对象则不会被当做垃圾收集. 因为没有任何其他对象所引用,所以无引用对象一定是不再使用的。 但是有一部分无用对象仍然被(无意中)引用着。这就是发生内存泄露的根源.
为什么内存会泄露?
让我们看下面的实例来了解为什么内存会泄露. 在下面的情境中,对象A引用了对象B. A的生命周期(t1 - t4) 比 B的(t2 - t3)要长得多. 当对象B在应用程序逻辑中不会再被使用以后, 对象 A 仍然持有着 B的引用. (根据虚拟机规范)在这种情况下垃圾收集器不能将 B 从内存中释放. 这种情况很可能会引起内存问题,假若A 还持有着其他对象的引用,那么这些被引用的(无用)对象都不会被回收,并占用着内存空间.
甚至有可能 B 也持有一大堆其他对象的引用。 这些对象由于被 B 所引用,也不会被垃圾收集器所回收. 所有这些无用的对象将消耗大量宝贵的内存空间。
怎么防止内存泄露?
要防止内存泄露,下面是一些快速上手的实用技巧:
1. 当心集合类,比如 HashMap,ArrayList等,因为这是最容易发生内存泄露的地方.当集合对象被声明为static时,他们的生命周期一般和整个应用程序一样长。
2. 注意事件监听和回调.当注册的监听器不再使用以后,如果没有被注销,那么很可能会发生内存泄露.
3. "当一个类自己管理其内存空间时,程序员应该注意内存泄露." 常常是一个对象的成员变量需要被置为null 时仍然指向其他对象,
一个小测验: 为什么 JDK6 中的 substring() 方法有可能导致内存泄露?
要回答这个问题,请参考: JDK6和JDK7中String的substring()方法及其差异
参考资料:
[1] Bloch, Joshua. Effective java. Addison-Wesley Professional, 2008.
[2] IBM Developer Work. http://www.ibm.com/developerworks/library/j-leaks/
相关文章:
1.
Java 对象在堆中的内存结构
2. Java 数组在内存中的结构
3. How is an array stored in memory and brought to cache?
4. Java String 常见问题
简述Java内存泄露的更多相关文章
- java内存泄露的理解与解决(转)
Java内存管理机制 在C++语言中,如果需要动态分配一块内存,程序员需要负责这块内存的整个生命周期.从申请分配.到使用.再到最后的释放.这样的过程非常灵活,但是却十分繁琐,程序员很容易由于疏忽而忘记 ...
- Java内存泄露的原因
Java内存泄露的原因 1.静态集合类像HashMap.Vector等的使用最容易出现内存泄露,这些静态变量的生命周期和应用程序一致,所有的对象Object也不能被释放,因为他们也将一直被Vector ...
- Java 内存泄露
一.Java内存回收机制 不论哪种语言的内存分配方式,都需要返回所分配内存的真实地址,也就是返回一个指针到内存块的首地址.Java中对象是采用new或者反射的方法创建的,这些对象的创建都是在堆(Hea ...
- Java 内存泄露的理解与解决过程
本文详细地介绍了Java内存管理的原理,以及内存泄露产生的原因,同时提供了一些列解决Java内存泄露的方案,希望对各位Java开发者有所帮助. Java内存管理机制 在C++ 语言中,如果需要动态分配 ...
- Java内存泄露监控工具:JVM监控工具介绍【转】
jstack?-- 如果java程序崩溃生成core文件,jstack工具可以用来获得core文件的java stack和native stack的信息,从而可以轻松地知道java程序是如何崩溃和在程 ...
- 关于java内存泄露的总结--引用的类型:强引用,弱引用,软引用
今天面试了一家公司的java开发方面的实习生,被问到一个问题:如何处理java中的内存泄露问题,保证java的虚拟机内存不会被爆掉,当时其实觉得面试官的问题有点泛,所以也没有很好领会他的意思,答案也不 ...
- Java内存泄露原因详解
一.Java内存回收机制 不论哪种语言的内存分配方式,都需要返回所分配内存的真实地址,也就是返回一个指针到内存块的首地址.Java中对象是采用new或者反射的方法创建的, 这些对象的创建都是在堆(He ...
- java内存泄露与内存溢出
内存溢出 out of memory,是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory: 内存泄露 memory leak,是指程序在申请内存后,无法释放已申请的内存空 ...
- Java内存泄露简述
Java的一个最显著的优势是内存管理.你只需要简单的创建对象而不需要负责释放空间,因为Java的垃圾回收器会负责内存的回收.然而,情况并不是这样简单,内存泄露还是经常会在Java应用程序中出现. 本篇 ...
随机推荐
- 独立游戏《Purgatory Ashes》的经验与总结
1.引子 游戏的灵感萌生于2015年,当时只有一些概念性的设计图. 后来我利用资源商店的素材搭建了最早的原型. 游戏的最终画面: 早期以D.P作为代号进行开发,来源于两个单词的缩写 Devil Pro ...
- 实验与作业(Python)-文件操作
1.CSV文件的处理 下载-身份证号文件 导入: 读入"身份证号.txt",然后打印出来.注意:是否多打了一行,为什么? 读入"身份证号.txt",然后存储到& ...
- 初识Spring Boot框架(二)之DIY一个Spring Boot的自动配置
在上篇博客初识Spring Boot框架中我们初步见识了SpringBoot的方便之处,很多小伙伴可能也会好奇这个Spring Boot是怎么实现自动配置的,那么今天我就带小伙伴我们自己来实现一个简单 ...
- 亲密接触Redis-第三天(Redis的Load Balance)
前言 上两天讲述了Redis的基本搭建和基于HA的集群布署方式以及相关的策略和注意点.今天开始讲述Redis的Cluster功能,而这块目前来说网上资料不是太全,就算有1,2篇也只是单讲服务端的搭建也 ...
- oracle手工生成AWR报告方法记录
AWR(Automatic Workload Repository)报告是我们进行日常数据库性能评定.问题SQL发现的重要手段.熟练掌握AWR报告,是做好开发.运维DBA工作的重要基本功. AWR报告 ...
- Java异常处理-----非运行时异常(受检异常)
非运行时异常(受检异常) 如果出现了非运行时异常必须进行处理throw或者try{}catch(){}处理,否则编译器报错. 1:IOException 使用要导入包import java.io.IO ...
- SpriteKit中为何不要在update方法中测试碰撞
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 我们若要在游戏中做碰撞检测有2种办法,一是利用物理引擎,二是自 ...
- Android Studio安装Genymotion插件
Android Studio安装Genymotion插件 Eclipse就不介绍了,谷歌都已经放弃Eclipse了,你还在坚持什么. 安装Genymotion 官网:https://www.genym ...
- FFmpeg的H.264解码器源代码简单分析:解析器(Parser)部分
===================================================== H.264源代码分析文章列表: [编码 - x264] x264源代码简单分析:概述 x26 ...
- shell的date日期循环方法:日期格式转时间戳计算,再将时间戳转回日期格式
1,日期对象转时间戳current_day 2,计算增量的时间戳,即循环每步的增量one_day 3,循环体计算,日期变量加增量后重新赋值自己 4,时间戳转回日期格式后输出 current_day=2 ...