十一城

跬步千里,小流江海。

Home Linux ML Python Java Thoughts KmKg BookCan Links About

2017-08-23
内存溢出与内存泄漏

• 分类: java • 标签:

今天我们站在JVM的角度来谈一谈内存溢出与内存泄漏的问题。

内存泄漏 Memory Leak

在计算机科学中,内存泄漏指由于疏忽或错误造成程序未能释放已经不再使用的内存。 内存泄漏并非指内存在物理上的消失,而是应用程序分配某段内存后,由于设计错误,导致在释放该段内存之前就失去了对该段内存的控制,从而造成了内存的浪费。

因为java new出的所有对象均是存储在jvm运行时数据区的堆中,所以内存泄漏就是发生在这个区域。内存泄露是指分配出去的内存没有被回收回来,由于失去了对该内存区域的控制,因而造成了资源的浪费。Java中一般不会产生内存泄露,因为有垃圾回收器自动回收垃圾,但这也不绝对,当我们new了对象,并保存了其引用,但是后面一直没用它,而垃圾回收器又不会去回收它,这边会造成内存泄露。

随着越来越多的服务器程序采用Java技术,例如JSP,Servlet, EJB等,服务器程序往往长期运行。另外,在很多嵌入式系统中,内存的总量非常有限。内存泄露问题也就变得十分关键,即使每次运行少量泄漏,长期运行之后,系统也是面临崩溃的危险。

对象的释放是由GC决定和执行的。在Java中,内存的分配是由程序完成的,而内存的释放是有GC完成的,这种收支两条线的方法确实简化了程序员的工作。但同时,它也加重了JVM的工作。这也是Java程序运行速度较慢的原因之一。因为,GC为了能够正确释放对象,GC必须监控每一个对象的运行状态,包括对象的申请、引用、被引用、赋值等,GC都需要进行监控。

内存溢出 Out of Memory

内存溢出是指程序所需要的内存超出了系统所能分配的内存(包括动态扩展)的上限。

这在java中往往体现为OutOfMemoryError异常,通常会出现以下几种情况:

  • Java堆溢出——jvm在启动的时候会以一个参数设置虚拟机的堆大小,当堆满即出现溢出。
  • 虚拟机和本地方法栈溢出
  • 方法区和运行时常量池溢出——方法区溢出也是一种常见的内存溢出异常,一个类要被垃圾回收器回收掉,判定条件是比较严苛的。在经常动态产生大量Class的应用中,需要特别注意类的回收状况。这类场景包括CGLib字节码增强、动态语言、大量JSP或者动态产生JSP文件的应用、基于OSGi的应用等
  • 本机直接内存溢出

参考:IBM


dzzxjl

Home Linux ML Python Java Thoughts KmKg BookCan Links About