内存泄露(memory leak) VS 内存溢出(out of memory)

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

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

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

GC为了能够正确释放对象,会监控每个对象的运行状况,对他们的申请、引用、被引用、赋值等状况进行监控,Java会使用有向图的方法进行管理内存,实时监控对象是否可以达到,如果不可到达,则就将其回收。

内存泄露可以通过完善代码来避免;内存溢出可以通过调整配置来减少发生频率,但无法彻底避免。

Java内存泄露根本原因:

  长生命周期的对象持有短生命周期对象的引用就很可能发生内存泄露,尽管短生命周期对象已经不再需要,但是因为长生命周期对象持有它的引用而导致不能被回收,这就是java中内存泄露的发生场景。具体主要有如下几大类:

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

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

  如果仅仅释放引用本身(o=null,表示o这个引用不在指向堆中的内存,但是vector这个引用没有释放,一直在引用原来o指向的内存),那么Vector 仍然引用该对象,所以这个对象对GC 来说是不可回收的。因此,如果对象加入到Vector 后,还必须从Vector 中删除,最简单的方法就是将Vector对象设置为null。

public class MemoryLeakTest {public static void main(String[] args) {Vector v = new Vector(10);for (int i = 1; i<100; i++){Object o = new Object();v.add(o);o = null;}//
    }
}

  2、  当集合里面的对象属性被修改后,再调用remove()方法时可能不起作用。

           考虑hanshMap中,key值如果变化,再remove是remote不掉了,就会导致内存泄漏。

  3、监听器 
  在java 编程中,我们都需要和监听器打交道,通常一个应用当中会用到很多监听器,我们会调用一个控件的诸如addXXXListener()等方法来增加监听器,但往往在释放对象的时候却没有记住去删除这些监听器,从而增加了内存泄漏的机会。

  4、各种连接 
  比如数据库连接(dataSourse.getConnection()),网络连接(socket)和io连接,除非其显式的调用了其close()方法将其连接关闭,否则是不会自动被GC 回收的。对于Resultset 和Statement 对象可以不进行显式回收,但Connection 一定要显式回收,因为Connection 在任何时候都无法自动回收,而Connection一旦回收,Resultset 和Statement 对象就会立即为NULL。但是如果使用连接池,情况就不一样了,除了要显式地关闭连接,还必须显式地关闭Resultset Statement 对象(关闭其中一个,另外一个也会关闭),否则就会造成大量的Statement 对象无法释放,从而引起内存泄漏。这种情况下一般都会在try里面去的连接,在finally里面释放连接。

  5、如果单例对象持有外部对象的引用,那么这个外部对象将不能被jvm正常回收,导致内存泄露

  不正确使用单例模式是引起内存泄露的一个常见问题,单例对象在被初始化后将在JVM的整个生命周期中存在(以静态变量的方式),如果单例对象持有外部对象的引用,那么这个外部对象将不能被jvm正常回收,导致内存泄露,考虑下面的例子:

那么如何避免内存泄漏:

  • 尽早释放无用对象的引用:使用临时变量的时候,让引用变量在退出活动域后自动设置为null,暗示垃圾收集器来收集该对象,防止发生内存泄露。
  • 进行字符串处理时,尽量避免使用String,而应使用StringBuffer。
  • 尽量少用静态变量
  • 避免集中创建对象尤其是大对象,如果可以的话尽量使用流操作
  • 尽量运用对象池技术以提高系统性能。
  • 不要在经常调用的方法中创建对象,尤其是忌讳在循环中创建对象

内存溢出的解决方案:

  • 是从代码层面进行优化完善,尽量避免该情况发生;
  • 二是调整优化服务器配置:

     具体内容参看其他相关话题(http://www.cnblogs.com/liufei1983/p/8996186.html)

二:java内存管理

  Java的内存管理就是对象的分配和释放问题。在Java中,内存 的分配是由程序完成的,而内存的释放是由垃圾收集器(GarbageCollection,GC)完成的,程序员不需要通过调用函数来释放内存,但它只能 回收无用并且不再被其它对象引用的那些对象所占用的空间。

  Java的内存垃圾回收机制是从程序的主要运行对象开始检查引用链,当遍历一遍后发现没有被引用的孤立对象就作为垃圾回收。GC为了能够正确释放对 象,必须监控每一个对象的运行状态,包括对象的申请、引用、被引用、赋值等,GC都需要进行监控。监视对象状态是为了更加准确地、及时地释放对象,而释放 对象的根本原则就是该对象不再被引用。

  比如在函数中,String s = new String("abc");  s是一个栈中的引用,指向堆中的对象, 当函数调用完后s这个引用就没有了,堆中的内存就会被释放。

  在Java中,这些无用的对象都由GC负责回收,因此程序员不需要考虑这部分的内存泄露。虽然,我们有几个函数可以访问GC,例如运行GC的函数 System.gc(),但是根据Java语言规范定义,该函数不保证JVM的垃圾收集器一定会执行。因为不同的JVM实现者可能使用不同的算法管理 GC。通常GC的线程的优先级别较低。JVM调用GC的策略也有很多种,有的是内存使用到达一定程度时,GC才开始工作,也有定时执行的,有的是平缓执行 GC,有的是中断式执行GC。但通常来说,我们不需要关心这些。

二 :如果出现内存溢出,如何调整虚拟参数

JVM初始分配的内存由-Xms指定,默认是物理内存的1/64;

JVM最大分配的内存由-Xmx指定,默认是物理内存的1/4。

JVM内存的最大值跟操作系统有很大的关系。32位处理器虽然可控内存空间有4GB,但是具体的操作系统会给一个限制,这个限制一般是2GB-3GB(一般来说Windows系统下为1.5G-2G,Linux系统下为2G-3G),而64bit以上的处理器就不会有限制了。

三: 如何检测内存泄漏, 分析DUMP文件

可以通过一些性能监测分析工具,如 JProfiler、Optimizeit Profiler。

转载于:https://www.cnblogs.com/liufei1983/p/8995986.html

java 基础知识学习 内存泄露(memory leak) VS 内存溢出(out of memory)以及内存管理...相关推荐

  1. JAVA基础知识学习全覆盖

    文章目录 一.JAVA基础知识 1.一些基本概念 1.Stringbuffer 2.局部变量成员变量 3.反射机制 4.protect 5.pow(x,y) 6.final ,finally,fina ...

  2. java基础知识学习小总结(一)

    此文转载自:https://blog.csdn.net/weixin_44734093/article/details/109715246 什么是java Java是一门面向对象编程语言,不仅吸收了C ...

  3. Java基础知识学习笔记总结

    Java学习笔记总结 java基础复习 1. 抽象类可以有构造器,可以有一个非抽象的父类 2. 垃圾回收机制回收的是堆里面的内存,栈里面的数据自动入栈自动出栈 3. 引用类型的数据在堆当中,内存中操作 ...

  4. java 基础知识学习2

    目录 目录 基础知识练习 String 类实现大小写转换的方法 截取字符串中的部分内容 用正则表达式判断手机号码是否合法 用字符串生成器追加字符 用连接运算符连接字符串 去除字符串中的首尾控格 获取字 ...

  5. Java基础知识学习:简单随手记录(3)

    学习视频链接:https://www.bilibili.com/video/BV1fh411y7R8?p=1&vd_source=1635a55d1012e0ef6688b3652cefcdf ...

  6. 超详细的java基础知识学习(java SE、javaEE)笔记 核心重点!

    标识符 Java 的标识符是由字母.数字.下划线_.以及美元符$组成,但是首字母不可以是数字.Java 标识符大小写敏感,长度无限制,不能是 Java 中的关键字.命名规则:要见名知意! u  变量要 ...

  7. Java基础知识学习:简单随手记录(1)

    学习视频链接:https://www.bilibili.com/video/BV1fh411y7R8?p=1&vd_source=1635a55d1012e0ef6688b3652cefcdf ...

  8. Java基础知识学习01-环境变量的配置、数据类型

    Java  SE(Java Platform Standard Edition)  标准版    用于桌面程序开发 Java EE (Java Platform  Enterprise Edition ...

  9. Java基础知识学习04-自定义类、ArrayList集合

    类与对象 类是一个模子,确定对象将会拥有的特征(属性)和行为(方法). 类的特征:类是对象的类型 具有相同属性和方法的一组对象的集合 类的组成:属性和方法 定义一个类:public class  类名 ...

  10. JAVA基础知识学习

    1.各个方面知识 很全面的知识总结(推荐): https://www.yuque.com/crow/simpread/23aba84d-73b3-4950-9621-bf511b2d088a#cf65 ...

最新文章

  1. 一人一天发两篇Science,配视频揭秘:植物如何在与病菌的斗争中取胜?
  2. ADAS关键技术剖析、应用现状以及发展趋势
  3. C# CheckBox与RadioButton
  4. IDEA中无法识别servlet类或找不到javax.servlet.*
  5. Selenium2Library+ride学习笔记
  6. git cherry-pick 复制其他分支内容到当前分支
  7. 【CCF】201903-1小中大
  8. [poj3280]Cheapest Palindrome_区间dp
  9. mysql6.7主从_CentOS 6.7下MySQL主从部署
  10. 计算机导论dos实验报告,计算机导论实验报告-DOS常用命令的使用.doc
  11. AD9361 介绍 (上)
  12. matlab数学实验 课件,MATLAB数学实验课件.PPT
  13. Windows/Linux/MacOS下VMware Workstation Pro/Vmware Fusion虚拟机的安装使用,Vmware Tools 的安装,Vmware使用技巧与故障排除。
  14. mro python_python MRO
  15. openGL学习之旅(一)DEV-C++安装GLUT
  16. 孩子被人欺负了,要不要打回去?非常赞同这位宝妈的做法
  17. 时序数据预测:Holt-Winters
  18. java jws web_基于Jws的WebService项目
  19. 最简单的无线充电传输电路
  20. 1D mesauring

热门文章

  1. Swagger 教程
  2. c语言else不运行,if...else if..else第三句不执行?
  3. mysql查看数据库表大小语句_MySQL查看数据库表容量大小的命令语句讲解
  4. 用java语言求前50个素数_Java求质数的几种常用算法总结
  5. kafka的push与poll
  6. Linux平台kafaka安装及使用
  7. cf 0.2 版本发布,lua 开发的另一种美
  8. 【高级编程技术作业】第六周
  9. flume介绍及应用
  10. STL - queue(队列)