Java的内存泄漏_与C/C++对比(转载总结)
原文网址:http://developer.51cto.com/art/201111/302465.htm
Java内存泄露的理解与解决(1)
一般来说内存泄漏有两种情况。一种情况如在C/C++ 语言中的,在堆中的分配的内存,在没有将其释放掉的时候,就将所有能访问这块内存的方式都删掉(如指针重新赋值);另一种情况则是在内存对象已经不需要的时候,还仍然保留着这块内存和它的访问方式(引用)。第一种情况,在 Java 中已经由于垃圾回收机制的引入,得到了很好的解决。所以, Java 中的内存泄漏,主要指的是第二种情况。
AD:
Java内存管理机制
在C++ 语言中,如果需要动态分配一块内存,程序员需要负责这块内存的整个生命周期。从申请分配、到使用、再到最后的释放。这样的过程非常灵活,但是却十分繁琐,程序员很容易由于疏忽而忘记释放内存,从而导致内存的泄露。 Java 语言对内存管理做了自己的优化,这就是垃圾回收机制。 Java 的几乎所有内存对象都是在堆内存上分配(基本数据类型除外),然后由 GC ( garbage collection)负责自动回收不再使用的内存。
上面是Java 内存管理机制的基本情况。但是如果仅仅理解到这里,我们在实际的项目开发中仍然会遇到内存泄漏的问题。也许有人表示怀疑,既然 Java 的垃圾回收机制能够自动的回收内存,怎么还会出现内存泄漏的情况呢?这个问题,我们需要知道 GC 在什么时候回收内存对象,什么样的内存对象会被 GC 认为是“不再使用”的。
J ava中对内存对象的访问,使用的是引用的方式。在 Java 代码中我们维护一个内存对象的引用变量,通过这个引用变量的值,我们可以访问到对应的内存地址中的内存对象空间。在 Java 程序中,这个引用变量本身既可以存放堆内存中,又可以放在代码栈的内存中(与基本数据类型相同)。 GC 线程会从代码栈中的引用变量开始跟踪,从而判定哪些内存是正在使用的。如果 GC 线程通过这种方式,无法跟踪到某一块堆内存,那么 GC 就认为这块内存将不再使用了(因为代码中已经无法访问这块内存了)。
通过这种有向图的内存管理方式,当一个内存对象失去了所有的引用之后,GC 就可以将其回收。反过来说,如果这个对象还存在引用,那么它将不会被 GC 回收,哪怕是 Java 虚拟机抛出 OutOfMemoryError 。
- Vector v = new Vector( 10 );
- for ( int i = 1 ;i < 100 ; i ++ ){
- Object o = new Object();
- v.add(o);
- o = null ;
- }
在这个例子中,代码栈中存在Vector 对象的引用 v 和 Object 对象的引用 o 。在 For 循环中,我们不断的生成新的对象,然后将其添加到 Vector 对象中,之后将 o 引用置空。问题是当 o 引用被置空后,如果发生 GC ,我们创建的 Object 对象是否能够被 GC 回收呢?答案是否定的。因为, GC 在跟踪代码栈中的引用时,会发现 v 引用,而继续往下跟踪,就会发现 v 引用指向的内存空间中又存在指向 Object 对象的引用。也就是说尽管 o 引用已经被置空,但是 Object 对象仍然存在其他的引用,是可以被访问到的,所以 GC 无法将其释放掉。如果在此循环之后, Object 对象对程序已经没有任何作用,那么我们就认为此 Java 程序发生了内存泄漏。
尽管对于C/C++ 中的内存泄露情况来说, Java 内存泄露导致的破坏性小,除了少数情况会出现程序崩溃的情况外,大多数情况下程序仍然能正常运行。但是,在移动设备对于内存和 CPU都有较严格的限制的情况下, Java 的内存溢出会导致程序效率低下、占用大量不需要的内存等问题。这将导致整个机器性能变差,严重的也会引起抛出 OutOfMemoryError ,导致程序崩溃。
一般情况下内存泄漏的避免
在不涉及复杂数据结构的一般情况下,Java 的内存泄露表现为一个内存对象的生命周期超出了程序需要它的时间长度。我们有时也将其称为“对象游离”。
例如:
- public class FileSearch{
- private byte [] content;
- private File mFile;
- public FileSearch(File file){
- mFile = file;
- }
- public boolean hasString(String str){
- int size = getFileSize(mFile);
- content = new byte [size];
- loadFile(mFile, content);
- String s = new String(content);
- return s.contains(str);
- }
- }
在这段代码中,FileSearch 类中有一个函数 hasString ,用来判断文档中是否含有指定的字符串。流程是先将mFile 加载到内存中,然后进行判断。但是,这里的问题是,将 content 声明为了实例变量,而不是本地变量。于是,在此函数返回之后,内存中仍然存在整个文件的数据。而很明显,这些数据我们后续是不再需要的,这就造成了内存的无故浪费。
要避免这种情况下的内存泄露,要求我们以C/C++ 的内存管理思维来管理自己分配的内存。第一,是在声明对象引用之前,明确内存对象的有效作用域。在一个函数内有效的内存对象,应该声明为 local 变量,与类实例生命周期相同的要声明为实例变量……以此类推。第二,在内存对象不再需要时,记得手动将其引用置空。
Java的内存泄漏_与C/C++对比(转载总结)的更多相关文章
- Java JVM 内存泄漏--全解析和处理办法 [ 转载 ]
Java JVM 内存泄露——全解析和处理办法 [转载] @author 小筐子 @address http://www.jianshu.com/p/bf159a9c391a JA ...
- Java的内存泄漏和垃圾回收机制
JAVA会产生内存泄露吗?首先,答案是肯定的. Java尽管有垃圾回收器,但依旧存在泄漏. Java内存泄漏跟C/C++内存泄漏的概念不一样:C/C++的内存泄漏是指Malloc了一些资源.最后没有f ...
- Java提高篇—— 简单介绍Java 的内存泄漏
java最明显的一个优势就是它的内存管理机制.你只需简单创建对象,java的垃圾回收机制负责分配和释放内存.然而情况并不像想像的那么简单,因为在Java应用中经常发生内存泄漏. 本教程演示了什么是内存 ...
- 什么是内存溢出以及java中内存泄漏5种情况的总结
内存泄漏定义(memory leak):一个不再被程序使用的对象或变量还在内存中占有存储空间. 一次内存泄漏似乎不会有大的影响,但内存泄漏堆积后的后果就是内存溢出.内存溢出 out of memory ...
- Java_内存泄漏_实例1
版权声明:本文为博主原创文章,转载请注明出处. 记一次压测时Java内存泄漏问题的发现过程(2017-08-14) [前篇] ①20170811进行A系统与B系统之间的会话功能进行压测,加上脚本准备期 ...
- 介绍 Java 的内存泄漏
java最明显的一个优势就是它的内存管理机制.你只需简单创建对象,java的垃圾回收机制负责分配和释放内存.然而情况并不像想像的那么简单,因为在Java应用中经常发生内存泄漏.脚本代码 本教程演示了什 ...
- java HashMap 内存泄漏
import java.util.HashMap; import java.util.Map; public class HashMapOver { public static void main(S ...
- MAT工具定位分析Java堆内存泄漏问题方法
一.MAT概述与安装 MAT,全称Memory Analysis Tools,是一款分析Java堆内存的工具,可以快速定位到堆内泄漏问题.该工具提供了两种使用方式,一种是插件版,可以安装到Eclips ...
- Java的内存泄漏
内存泄漏是指,无用对象(不再使用的对象)持续占用内存或者无用对象的内存得不到及时释放,从而造成的内存浪费 就说是有一块内存你不需要再用了,但是呢你还保留着它的指针,那么这块内存就不会被回收 举个例子 ...
随机推荐
- [Objective-c 基础 - 3.2] ARC
A.ARC的基本原理 1.ARC的判断原则:只有没有强指针指向对象,就会立即释放对象 注意,在以下情况,会立即回收内存: (1)指针超出作用域 { Person *p1 = [[Personalloc ...
- Qt Creator编辑器乱问题
新安装的Qt Creator 打开原来的工程源码时提示:无法用 "UTF-8"-编码解码 "main.cpp". 无法编辑 解决办法:修改项目属性的编辑器设 ...
- Java任务调度
最近项目要用到任务调度的相关知识,昨天信心满满的去官网学习,结果被坑个半死,我用的最新版的quartz,文档里说是兼容所有版本,但是代码连编译都报错,无奈只好从网上找资料,摸着石头过河总算有点眉目,在 ...
- 从Web借鉴UI设计
从Web借鉴UI设计 用户体验已经成为衡量应用软件质量的重要标准.在过去我们可能会惊叹于某个Web应用的华丽界面,现在,随着HTML5的强势登场,各类表现层技术及开发框架的发布,Web与窗体应用的界限 ...
- Winfrom巧用Using设置鼠标为WaitCursor
本文转载:http://www.cnblogs.com/LoveJenny/archive/2013/03/13/2956922.html 看到try,finally ,有没有让你想到什么呢?,对了u ...
- Sublime Text 2&3中输入法不跟随光标移动的问题的解决方法
插件名称:IMESupport GitHub页面:https://github.com/chikatoike/IMESupport 安装方法: 手动安装和通过Package Control在线安装. ...
- Android在MediaMuxer和MediaCodec用例 - audio+video
在Android多媒体类,MediaMuxer和MediaCodec这是一个相对年轻,他们是JB 4.1和JB 4.3据介绍. 前者被用来产生一个混合的音频和视频的多媒体文件.的缺点是,现在可以只支持 ...
- android学习日记08--Paint画笔
Paint 要绘图,首先得调整画笔,待画笔调整好之后,再将图像绘制到画布Canvas上,这样才可以显示在手机屏幕上.Android 中的画笔是 Paint类,Paint 中包含了很多方法对其属性进行设 ...
- js 数组排序要注意的问题,返回的值最好为 -1, 0, 1之间的值
var test10Elements = [7, 6, 5, 4, 3, 2, 1, 0, 8, 9]; var comparefn = function (x, y) { return x - y; ...
- [JavaScript]JS对select动态options操作[IE&FireFox兼容]
<select id="ddlResourceType" onchange="getvalue(this)"></select> ...