我门说一下,哪些区域可能发生OOM

我门一般将区域分为

程序计数器,每个线程内部的程序计数器

JAVA虚拟栈,Java栈,每个线程创建时候都创建一个虚拟机栈,保存一个个的栈帧

堆Heap Java内存管理的核心区域,放置Java对象实例,几乎所有创建Java对象都在堆上

方法区,所有线程共享的区域,存储所谓的元数据 对应的运行时常量池 字段 方法代码 类结构

运行时常量池,方法区一部分,放各种常量信息

本地方法栈,Java虚拟机栈类似,对本地方法的支持

那么我们这次是对于Java 6之后的变化进行的介绍

我们本次会说一下的广义上的JVM内存结果或者Java进程内存结构

可能出现OOM的内存区域

首先是关于内存结构图

图片

我们在上面的图中标出

直接内存是指的Direct Buffer所分配的内存,虽然一般说其不是JVM 内存的一部分

JVM是一个本地程序,所以必然需要其他的内存去完成基本任务,JIT等,并将编译后的方法存储在Code Cache中

然后说明一些问题

Java对象的创建是不是在堆上,因为有着逃逸分析的概念,JVM会在栈上分配不会逃逸的对象,这样做其实取决于JVM设计者的选择

而且在Java 7之后,元数据区取代了永久代,所以Intern字符串分配直接在堆上了

然后是OOM出现的原因

首先是堆空间的不足,首先想的就是堆的大小不合理,没有显式的指定JVM堆或者数值偏小

对于Java虚拟机栈或者本地方法区,可能出现的是StackOverFlowError,当栈去试图扩展时候失败,也会出现OOM

对于老版本的JDK ,因为永久代的大小有限,且回收不积极,所以可能导致OOM,诸如的导致有Intern 字符串缓存占用太多空间

直接内存不足也会导致OOM

发表评论

邮箱地址不会被公开。 必填项已用*标注