JAVA OOM总结

  首先,JVM除了程序计数器之外,都可能发生内存溢出OutOfMemoryError(OOM)异常。这里主要对可能发生内存溢出的区域,原因进行总结。

1.JAVA虚拟机栈

  虚拟机栈是线程私有的,虚拟机栈主要存储局部变量。Java虚拟机规范中,规定了此区域会抛出两种异常:

(1)如果请求栈深度大于虚拟机允许的深度,即涉及到方法层级调用太多,超过一定限度,将抛出StackOverflowError异常;这里说的栈的深度主要是java启动参数中xss参数,虚拟机栈大小配置;

(2)虚拟机栈动态扩展,如果得不到足够的内存申请空间,就会抛出OOM异常;虚拟机栈动态扩展,即当栈空间不够的时候,会自动加大栈的空间,避免StackOverflowError,此时申请空间不足,便会OOM,部分虚拟机具备这个功能;

2.本地方法栈

  本地方法栈是为Native方法方法服务的,与虚拟机栈一样,本地方法栈也会抛出OOM以及StackOverflowError异常;

3.JAVA堆

  JAVA堆是内存管理最大的一块,是所有线程共享的一块区域,在虚拟机启动的时候创建,主要存储对象实例。这块主要通过启动参数-Xmx进行配置,如果申请的对象实例大小超过该配置的参数,便出现OOM异常。内存泄漏也会导致该区域的OOM,内存泄漏会导致不能回收的对象停留在堆中,随着时间推移便会消耗完堆空间出发OOM。

4.方法区

  方法区和java堆一样,是各个线程共享的内存区域,用于存储已被虚拟机加载的类信息,常量、静态变量和即时编译器编译后的代码数据。当方法区无法满足内存分配,将抛出OOM异常。

  当前的一些框架,如Spring、Hibernate等,会使用CGlib技术对类进行增强,相应地会增加类的大小;
  还有一些应用,会动态生成JSP文件,JSP文件是需要编译成Class文件的,大量的文件也有溢出的可能;
  或者开发代码中往常量池添加过多的常量,也有可能造成常量池溢出。
  另外一种可能就是我们的应用本身的类就太多,而方法区设置的容量不足,也会容易溢出。
  设置方法区的大小,可通过配置-XX:PremSize 设置最小值,-XX:MaxPremSize设置最大值。
5.直接内存

  直接内存(Direct Memory)又称堆外内存,内存对象分配在Java虚拟机的堆以外的内存,这些内存直接受操作系统管理(而不是虚拟机);

  (1)减少了垃圾回收

  使用堆外内存的话,堆外内存是直接受操作系统管理( 而不是虚拟机 )。这样做的结果就是能保持一个较小的堆内内存,以减少垃圾收集对应用的影响。

  (2)提升复制速度(io效率)

  堆内内存由JVM管理,属于“用户态”;而堆外内存由OS管理,属于“内核态”。如果从堆内向磁盘写数据时,数据会被先复制到堆外内存,即内核缓冲区,然后再由OS写入磁盘,使用堆外内存避免了这个操作。

  如果堆外内存申请超过,物理内存的限制也会出现OOM异常。

  

原文地址:https://www.cnblogs.com/vimzhu/p/11482361.html

时间: 2024-10-09 03:05:16

JAVA OOM总结的相关文章

Java OOM学习

转载自原文: 什么是java OOM?如何分析及解决oom问题? 什么是OOM? OOM,全称"Out Of Memory",翻译成中文就是"内存用完了",表现形式就是"java.lang.OutOfMemoryError".异常.看下官方的说明: Thrown when the Java Virtual Machine cannot allocate an object because it is out of memory, and no m

java oom一例

这几天和同事一起分析的一个线上的java应用. 线上查询平台应用,主要原理是用户传入sql,经由查询平台通过jdbc连接hive做查询操作. 主要架构:user---->tengine---->java--->haproxy---->hiveserver2 线上用户反映查询异常,分析tengine的访问日志,发现部分响应的http code是499(和之前处理的resin accesslog问题一样),怀疑是后端不响应,导致用户访问时立即抛出异常,分析nginx的error log

java——OOM内存泄漏

资料: 一.什么是OOM OOM,全称“Out Of Memory”,翻译成中文就是“内存用完了”,当JVM因为没有足够的内存来为对象分配空间并且垃圾回收器也已经没有空间可回收时,就会抛出这个error 二.为什么会OOM.出现的原因是什么 为什么会没有内存了呢?原因不外乎有两点: ① 分配的少了:比如虚拟机本身可使用的内存(一般通过启动时的VM参数指定)太少. ② 应用用的太多,并且用完没释放,浪费了.此时就会造成内存泄露或者内存溢出. 三.解决办法 ① java.lang.OutOfMemo

Java OOM

https://docs.oracle.com/javase/7/docs/webnotes/tsg/TSG-VM/html/memleaks.html http://docs.oracle.com/javase/6/docs/technotes/guides/visualvm/index.html https://visualvm.java.net/ https://dzone.com/articles/visualvm-see-whats-your-heap https://dzone.co

记录我遇到过的Java面试技术问题

1. Java Memory model execution engineer: java stack/pc registers/native|direct memory area/java heap/method area volatile: thread = its own stack + memory cache inside CPU, volatile can make sure read/write directly to main memory data, not local cpu

Java 内存溢出排查

Java OOM 毫无疑问是开发人员常见并且及其痛恨的问题,但是任何服务的开发都没法避免 OOM. 因此,OOM 的排查及定位是每个 Java 工程师都必备的技能. 所遇到的问题在使用 scala 开发的一个 web 服务,在用户使用中,经常出现: java.lang.OutOfMemoryError: Java heap space .而且还束手无策,每次都只能重启服务解决. 准备服务使用 jetty 发布的,先来看一下我这个服务的启动参数: /opt/soft/jdk/jdk1.7.0_40

Java进程内存泄漏判断及解决方法

内存泄漏种类Java使用的内存种类包含三种,这三种类型的内存都可能发生内存泄漏.? 堆内存泄漏,如果JVM 不能在java 堆中获得更多内存来分配更多java 对象,将会抛出java堆内存不足(java OOM) 错误.如果java 堆充满了活动对象,并且JVM 无法再扩展java 堆,那么它将不能分配更多java 对象.更多情况是程序设计有问题,生成的对象占用过多的堆内存造成堆内存泄漏.? 本地内存泄漏, 如果JVM 无法获得更多本地内存,它将抛出本地OOM错误.当进程用到的内存到达操作系统的

Android Image Loader 第三方库对比测试

预热知识 测试前,我们需要先明白这样一个问题 Java Heap / Native Heap 各自代表什么? Bitmap 到底是分配在Java heap上 还是分配到了Native heap上 Java Heap 大小一般是多大,有限制吗? Native Heap大小一般是多大,有限制吗? Java OOM 一般是发生在什么时候,和Java Heap有关还是和 Native Heap有关 如果以上问题不是很清楚的话可以参考这个链接,自己恶补一下基础知识:Android进程的内存管理分析 关于上

HBase 中的 JVM 与 GC

HBase中JVM基本配置 在JVM中,默认情况下会设置minimum heap size 为 1/64 可用物理内存,并为maximum heap size设置 1/4 的物理可用内存(不过在Java8 之前,默认最大是1g).当然,我们可以通过手动指定 JVM 参数,配置JVM的内存,例如: -Xms10g -Xmx10g 在HBase 中,也可以在 hbase-env.sh 中显示指定堆内存大小,例如: # The maximum amount of heap to use. Defaul