内存区域和内存溢出异常
程序计数器(线程私有)
描述
每条线程都需要一个独立的程序计数器,它们互相独立互不影响。
-
如果当前在执行一个java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址
-
如果正在执行的是一个Native方法,这个计数器值为空
java虚拟机栈
没规定OOM 内存溢出
Java虚拟机栈(线程私有)
虚拟机栈描述的是java方法执行的内存模型:每个方法执行的同时都会创建一个栈帧用于存储局部变量表、操作数栈、动态链接、方法出口等信息。每一个方法从调用知道执行完毕的过程,就对应这一个栈帧在虚拟机栈 入栈和出栈的过程,
本地方法栈(线程私有)
作用玩去那一样,区别为使用Native方法使用
堆(线程共享)
堆是JVM所管理的最大一块内存区域,同时是所有线程共享的区域,在jvm启动的时候创建,堆中存放的都是对象实例,
堆是内存回收管理的主要区域,因此对被称为gc堆,
如果堆中没有内存完成实例分配且无法进行再扩展的时候.将会抛出OO异常
JVM规定所有对象实例和数组都要在堆上分配,且堆可以存在于物理上的不连续内存空间.并且在主流虚拟机中堆的大小都是可以进行扩展,使用-Xmx设置最大值, -Xms设置最小值
方法区(线程共享)
方法区与java堆一样,是各个线程共享的内存区域,被用于存储已经被虚拟机加载的类信息,常量,静态变量,即时编译器编译后的diamante等数据,在JDK8之前的HotSpot虚拟机中,方法区被称为永久代,现在被元空间取代
永久代并不意味着数据进入方法区就永久存在,此区域的内存回收主要是针对常量池的回收以及对类型的卸载。
JVM规范规定:当方法区无法满足内存分配需求时,将抛出OOM异常。
运行时常量池(方法区的一部分)
运行时常量池是方法区的一部分,存放字面量与符号引用。
字面量 : 字符串(JDK1.7后移动到堆中) 、final常量、基本数据类型的值。
符号引用 : 类和结构的完全限定名、字段的名称和描述符、方法的名称和描述符。