一、基本概念

内存溢出:简单地说内存溢出就是指程序运行过程中申请的内存大于系统能够提供的内存,导致无法申请到足够的内存,于是就发生了内存溢出。

内存泄漏:内存泄漏指程序运行过程中分配内存给临时变量,用完之后却没有被GC回收,始终占用着内存,既不能被使用也不能分配给其他程序,于是就发生了内存泄漏。


内存溢出 out of memory,是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory;

内存泄露 memory leak,是指程序在申请内存后,无法释放已申请的内存空间,一次内存泄露危害可以忽略,但内存泄露堆积后果很严重,无论多少内存,迟早会被占光。

memory leak会最终会导致out of memory!

内存泄露是指无用对象(不再使用的对象)持续占有内存或无用对象的内存得不到及时释放,从而造成的内存空间的浪费称为内存泄露。内存泄露有时不严重且不易察觉,这样开发者就不知道存在内存泄露,但有时也会很严重,会提示你Out of memory。

二、内存溢出的常见情况

内存溢出有以下几种常见的情况:

1、java.lang.OutOfMemoryError: PermGen space (持久带溢出)

我们知道jvm通过持久带实现了java虚拟机规范中的方法区,而运行时常量池就是保存在方法区中的,因此发生这种溢出可能是运行时常量池溢出,或是由于程序中使用了大量的jar或class,使得方法区中保存的class对象没有被及时回收或者class信息占用的内存超过了配置的大小。

2、java.lang.OutOfMemoryError: Java heap space (堆溢出)

发生这种溢出的原因一般是创建的对象太多,在进行垃圾回收之前对象数量达到了最大堆的容量限制。

解决这个区域异常的方法一般是通过内存映像分析工具对Dump出来的堆转储快照进行分析,看到底是内存溢出还是内存泄漏。如果是内存泄漏,可进一步通过工具查看泄漏对象到GC Roots的引用链,定位出泄漏代码的位置,修改程序或算法;如果不存在泄漏,就是说内存中的对象确实都还必须存活,那就应该检查虚拟机的堆参数-Xmx(最大堆大小)和-Xms(初始堆大小),与机器物理内存对比看是否可以调大。

3、虚拟机栈和本地方法栈溢出

如果线程请求的栈深度大于虚拟机所允许的最大深度,将抛出StackOverflowError。

如果虚拟机在扩展栈时无法申请到足够的内存空间,则抛出OutOfMemoryError。

三、内存泄漏

内存泄漏的根本原因是长生命周期的对象持有短生命周期对象的引用,尽管短生命周期的对象已经不再需要,但由于长生命周期对象持有它的引用而导致不能被回收。

以发生的方式来分类,内存泄漏可以分为4类:

1、常发性内存泄漏。发生内存泄漏的代码会被多次执行到,每次被执行的时候都会导致一块内存泄漏。

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

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

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

从用户使用程序的角度来看,内存泄漏本身不会产生什么危害,作为一般的用户,根本感觉不到内存泄漏的存在。真正有危害的是内存泄漏的堆积,这会最终消耗尽系统所有的内存。从这个角度来说,一次性内存泄漏并没有什么危害,因为它不会堆积,而隐式内存泄漏危害性则非常大,因为较之于常发性和偶发性内存泄漏它更难被检测到。

下面总结几种常见的内存泄漏:

1、静态集合类引起的内存泄漏:

像HashMap、Vector等的使用最容易出现内存泄露,这些静态变量的生命周期和应用程序一致,他们所引用的所有的对象Object也不能被释放,从而造成内存泄漏,因为他们也将一直被Vector等引用着。

Vector v=new Vector(100);for (int i = 1; i<100; i++){Object o = new Object();v.add(o);o = null;}

在这个例子中,循环申请Object 对象,并将所申请的对象放入一个Vector 中,如果仅仅释放引用本身(o=null),那么Vector 仍然引用该对象,所以这个对象对GC 来说是不可回收的。因此,如果对象加入到Vector 后,还必须从Vector 中删除,最简单的方法就是将Vector对象设置为null。

2、修改HashSet中对象的参数值,且参数是计算哈希值的字段

当一个对象被存储到HashSet集合中以后,修改了这个对象中那些参与计算哈希值的字段后,这个对象的哈希值与最初存储在集合中的就不同了,这种情况下,用contains方法在集合中检索对象是找不到的,这将会导致无法从HashSet中删除当前对象,造成内存泄漏,举例如下:

public static void main(String[] args){ Set set = new HashSet(); Person p1 = new Person("张三

spark如何防止内存溢出_什么叫内存溢出?内存泄漏的定义又是什么?使用中如何避免?...相关推荐

  1. java docx 内存溢出_第2章 Java内存区域与内存溢出异常

    本章主要介绍了Java的内存区域以及会触发对应区域内存溢出的触发条件及表现结果.同时还对java对象的内存布局进行了简单的讲解. 2.2 运行时数据区域: 比较直观的一张图来表示: Java虚拟机运行 ...

  2. 我的世界java内存不足_[菜鸟级]简单解决内存溢出内存不足、卡机问题(可当启动器使用)...

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 好吧,该死的度娘破坏了格式,下面才是整理好格式的版本: ================================================= ...

  3. java jvm内存地址_深入Java虚拟机——JVM内存详解

    在C++中,程序员拥有每一个对象的所有权,但与此同时还肩负着释放对象内存空间的责任:而Java由于有了虚拟机的帮助,程序员拥有对象的所有权的同时不再需要释放对象的内存空间.由于是JVM自动进行对象内存 ...

  4. java主要内存区域_可能是把Java内存区域讲的最清楚的一篇文章

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 介绍下 Java 内存区域(运行时数据区) Java 对象的创建过程(五步,建议能默写出来并且要知道每一步虚拟机做了什么) 对象的访问定位的两种方式(句柄 ...

  5. C语言与JAVA内存管理_深入理解C语言内存管理

    之前在学Java的时候对于Java虚拟机中的内存分布有一定的了解,但是最近在看一些C,发现居然自己对于C语言的内存分配了解的太少. 问题不能拖,我这就来学习一下吧,争取一次搞定. 在任何程序设计环境及 ...

  6. python 单例模式内存泄露_彻底搞懂Java内存泄露

    之前一直在简书写作,第一次发布到SF上来,也是第一次使用SF,后面会尽量同步到SF,更多文章请关注: 简书 编程之乐 转载请注明出处:谢谢! Java内存回收方式 Java判断对象是否可以回收使用的而 ...

  7. java jvm 内存参数_深入详解JVM内存模型与JVM参数详细配置

    对于大多数应用来说,Java 堆(Java Heap)是Java 虚拟机所管理的内存中最大的一块.Java 堆是被所有线程共享的一块内存区域,在虚拟机启动时创建. JVM内存结构 由上图可以清楚的看到 ...

  8. java 内存管理_高性能Java代码之内存管理

    本文通过几个方面,来介绍Java代码的内存管理. 有的代码,GC根本就回收不了,直接系统挂掉.GC是一段程序,不是智能,他只回收他认为的垃圾,而不是回收你认为的垃圾. GC垃圾回收: Grabage ...

  9. 怎样清理苹果手机内存空间_苹果机天天显示内存不足,怎样能快速有效的清理内存?长知识了...

    苹果机天天显示内存不足,怎样能快速有效的清理内存?长知识了 苹果手机的内存空间向来都是人们比较吐槽的点,每一个内存区间的差价高达一千元.很多人可能就会考虑是不是买一个空间稍微小一点的,节约钱的同时,性 ...

最新文章

  1. 大规模集群中Docker镜像如何分发管理?试试Uber刚开源的Kraken
  2. java 单机版_JAVA单机版管理系统源代码.pdf
  3. SpringBoot跨域请求
  4. ​50年来最具影响力的十大编程语言
  5. git全局配置用户名和密码_git---全局设置用户名、密码、邮箱
  6. 温故而知新:查看端口占用情况以及DOS中的管道操作/重定向操作
  7. 【日常】ICS的lab7攻略和最近生活的吐槽
  8. 让我们用心感受泛型接口的协变和抗变out和in
  9. 手机号识别轻松对着号码扫一扫就录入了
  10. 通信原理及系统系列7—— 什么是码间串扰
  11. 显著性检验:P值和置信度
  12. 想要专升本你不得不看的全干货_吐血整理_专升本_计算机文化基础(七)
  13. openwrt环境下,使用externel commissioning组网openthread
  14. Python读xml
  15. STM32|HSE/HSI调频
  16. 虚拟拨号服务器名称,怎么设置虚拟拨号服务器
  17. 计算机机房装修效果图,机房装修施工流程是什么? 机房装修效果图
  18. SpringBoot重启后,第一次请求接口请求慢的解决方案
  19. 编程金融小白学 股票期权 lv.5 希腊字母 Delta
  20. vlookup java_Vlookup的VBA错误处理

热门文章

  1. sklearn之Multioutput 估计器
  2. Java开发必须要掌握的20个核心技术
  3. python修饰符用法_c#教程之C#语言中的修饰符汇总
  4. python将图片原比例缩小_Python实现图片长宽比例缩放和填充
  5. excel填充序列_零基础、初学者必须掌握的10个Excel技巧,办公必备!
  6. 七牛云 转码_YYC松鼠短视频系统V2.0版本发布,亮点新增转码加水印功能
  7. [专栏精选]2018.3地形更新详解
  8. .NET Core 3.0中的Cookie身份验证
  9. mr图像翻转的原因_MR成像技术讲解
  10. 基片集成波导原理_第5讲基片集成波导.ppt