Java内存泄漏与内存溢出详解

内存泄漏指你用malloc或new申请了一块内存,但是没有通过free或delete将内存释放,导致这块内存一直处于占用状态。

内存溢出指你申请了10个字节的空间,但是你在这个空间写入11或以上字节的数据,就是溢出。



内存泄露是指程序中间动态分配了内存,但在程序结束时没有释放这部分内存,从而造成那部分内存不可用的情况,重启计算机可以解决,但也有可能再次发生内存泄露,内存泄露和硬件没有关系,它是由软件设计缺陷引起的。

内存泄漏可以分为4类:
1)常发性内存泄漏。发生内存泄漏的代码会被多次执行到,每次被执行的时候都会导致一块内存泄漏。

2)偶发性内存泄漏。发生内存泄漏的代码只有在某些特定环境或操作过程下才会发生。常发性和偶发性是相对的。对于特定的环境,偶发性的也许就变成了常发性的。所以测试环境和测试方法对检测内存泄漏至关重要。

3)一次性内存泄漏。发生内存泄漏的代码只会被执行一次,或者由于算法上的缺陷,导致总会有一块仅且一块内存发生泄漏。比如,在类的构造函数中分配内存,在析构函数中却没有释放该内存,所以内存泄漏只会发生一次。

4)隐式内存泄漏。程序在运行过程中不停的分配内存,但是直到结束的时候才释放内存。严格的说这里并没有发生内存泄漏,因为最终程序释放了所有申请的内存。但是对于一个服务器程序,需要运行几天,几周甚至几个月,不及时释放内存也可能导致最终耗尽系统的所有内存。所以,我们称这类内存泄漏为隐式内存泄漏。

内存溢出即用户在对其数据缓冲区操作时,超过了其缓冲区的边界;尤其是对缓冲区写操作时,缓冲区的溢出很可能导致程序的异常。



Java内存泄露与溢出的区别

内存溢出就是你要求分配的内存超出了系统能给你的,系统不能满足需求,于是产生溢出。

Java内存泄漏就是没有及时清理内存垃圾,导致系统无法再给你提供内存资源(内存资源耗尽)。

看到上面的解释,可能有些朋友还是不太理解吧。没问题,看以下例子:

1.Java内存泄露是说程序逻辑问题,造成申请的内存无法释放.这样的话无论多少内存,早晚都会被占用光的.
最简单的例子就是死循环了.由于程序判断错误导经常发生此事。

2.Java内存泄漏是指在堆上分配的内存没有被释放,从而失去对其控制。这样会造成程序能使用的内存越来越少,导致系统运行速度减慢,严重情况会使程序当掉。

3.关于内存溢出有点出入。比如说你申请了一个integer,但给它存了long才能存下的数,那就是内存溢出。

举个现实中的例子:
比如有一个桶,装满了水.你丢个苹果进去。桶的水正常。如果你放个大石头。水就出溢出,内存溢出也就是这个原理。
区别:内存溢出,提供的内存不够;Java内存泄漏,无法再提供内存资源。



相关问题

Q:Java中会存在内存泄漏吗?
A: Java中也存在内存泄露。当被分配的对象可达但已无用(未对作废数据内存单元的引用置null)即会引起。

Q: 如何避免内存泄露、溢出?
A: 1)尽早释放无用对象的引用。

好的办法是使用临时变量的时候,让引用变量在退出活动域后自动设置为null,暗示垃圾收集器来收集该对象,防止发生内存泄露。

2)程序进行字符串处理时,尽量避免使用String,而应使用StringBuffer。

3) 尽量少用静态变量。

因为静态变量是全局的,GC不会回收。

4)避免集中创建对象尤其是大对象,如果可以的话尽量使用流操作。

5)尽量运用对象池技术以提高系统性能。

生命周期长的对象拥有生命周期短的对象时容易引发内存泄漏,例如大集合对象拥有大数据量的业务对象的时候,可以考虑分块进行处理,然后解决一块释放一块的策略。

6)不要在经常调用的方法中创建对象,尤其是忌讳在循环中创建对象。

可以适当的使用hashtable,vector创建一组对象容器,然后从容器中去取那些对象,而不用每次new之后又丢弃。

7) 优化配置。

时间: 2024-08-24 10:51:29

Java内存泄漏与内存溢出详解的相关文章

Android 有效的解决内存泄漏的问题实例详解

Android 有效的解决内存泄漏的问题 Android内存泄漏,我想做Android 应用的时候遇到的话很是头疼,这里是我在网上找的不错的资料,实例详解这个问题的解决方案 前言:最近在研究Handler的知识,其中涉及到一个问题,如何避免Handler带来的内存溢出问题.在网上找了很多资料,有很多都是互相抄的,没有实际的作用. 本文的内存泄漏检测工具是:LeakCanary  github地址:https://github.com/square/leakcanary 什么是内存泄漏? 内存泄漏

C++内存泄漏及检测工具详解_C 语言

首先我们需要知道程序有没有内存泄露,然后定位到底是哪行代码出现内存泄露了,这样才能将其修复. 最简单的方法当然是借助于专业的检测工具,比较有名如BoundsCheck,功能非常强大,相信做C++开发的人都离不开它.此外就是不使用任何工具,而是自己来实现对内存泄露的监控,分如下两种情况: 一. 在 MFC 中检测内存泄漏 假如是用MFC的程序的话,很简单.默认的就有内存泄露检测的功能. 我们用VS2005生成了一个MFC的对话框的程序,发现他可以自动的检测内存泄露.不用我们做任何特殊的操作. 仔细

科普:内存泄漏与内存溢出

最近项目中频繁出现OOM的问题,各种路径测试.内存走向分析.各种逻辑推理才最终定位到问题.在这过程中和组内的同学讨论的时候发现有的同学对内存泄漏和内存溢出的概念理解不到位,导致沟通过程比较尴尬.很多同学对这两个概念理解不够透彻,在项目中频繁写出内存泄漏的低级代码出来.结合自己的理解我写一篇文章理解下这两个概念. 内存泄漏 内存泄漏是指那些本应该回收(不再使用)的内存对象无法被系统回收的现象.在c++中需要程序猿手动释放内存对象,所以在C++中更容易存在内存泄漏.java引入了自动回收机制,使得在

多用多学之Java中的Set,List,Map详解_java

很长时间以来一直代码中用的比较多的数据列表主要是List,而且都是ArrayList,感觉有这个玩意就够了.ArrayList是用于实现动态数组的包装工具类,这样写代码的时候就可以拉进拉出,迭代遍历,蛮方便的. 也不知道从什么时候开始慢慢的代码中就经常会出现HashMap和HashSet之类的工具类.应该说HashMap比较多一些,而且还是面试经典题,平时也会多看看.开始用的时候简单理解就是个键值对应表,使用键来找数据比较方便.随后深入了解后发现 这玩意还有点小奥秘,特别是新版本的JDK对Has

系统-Java: ActionListener类的方法actionPerforme()详解

问题描述 Java: ActionListener类的方法actionPerforme()详解 谁知道系统工作的具体原理,就想了解这个.因为API给的解释就是一句:发生操作时调用. 这个解释实在是太透明了.

java 装饰模式(Decorator Pattern)详解_java

装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构.这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装. 这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能. 我们通过下面的实例来演示装饰器模式的使用.其中,我们将把一个形状装饰上不同的颜色,同时又不改变形状类. 实现 我们将创建一个 Shape 接口和实现了 Shape 接口的实体类.然后我们创建一个实现了 Shape 接口的抽象装饰类Sha

Java并发编程总结——慎用CAS详解_java

一.CAS和synchronized适用场景 1.对于资源竞争较少的情况,使用synchronized同步锁进行线程阻塞和唤醒切换以及用户态内核态间的切换操作额外浪费消耗cpu资源:而CAS基于硬件实现,不需要进入内核,不需要切换线程,操作自旋几率较少,因此可以获得更高的性能. 2.对于资源竞争严重的情况,CAS自旋的概率会比较大,从而浪费更多的CPU资源,效率低于synchronized.以java.util.concurrent.atomic包中AtomicInteger类为例,其getAn

Java Web请求与响应实例详解_java

Servlet最主要作用就是处理客户端请求并作出回应,为此,针对每次请求,Web容器在调用service()之前都会创建两个对象,分别是HttpServletRequest和HttpServletResponse.其中HttpServletRequest封装HTTP请求消息,HttpServletResponse封装HTTP响应消息.需要注意的是,Web服务器运行过程中,每个Servlet都会只创建一个实例对象,不过每次请求都会调用Servlet实例的service(ServletRequest

关于java.lang.string.format()方法的详解,网上百度 只有英文的,看不懂;

问题描述 关于java.lang.string.format()方法的详解,网上百度 只有英文的,看不懂: 关于java.lang.string.format()方法的详解,网上百度 只有英文的,看不懂: 解决方案 下个api,有中文版的,里面有介绍而且有简单示例的 解决方案二: 跟C语言的pringf的格式差不多 解决方案三: 是printf,,,,,,,,