JAVA虚拟机运行时内存划分--运行时数据区域
Java虚拟机在执行java程序时会把内存划分为以下几个不同的数据区域:
java虚拟机内存划分(运行时)
1、线程私有的:
程序计数器(Program Counter Register):可以看作当前线程所执行的字节码的行号指示器。java多线程中一个时刻,一个处理器都只会执行一条线程中的指令,在线程轮流切换的过程中,每个线程都有自己的程序计数器,互不影响,以便线程切换恢复到正确的执行位置。唯一不会发生OutOfMemoryError的区域。如果执行的是java方法,计数器值为虚拟机字节码指令地址;如果执行native方法,值为空。
java虚拟机栈(VM Stack):生命周期同线程相同,描述的是Java方法执行的内存模型:每个方法在执行的同时都会创建一个栈帧,用于存储局部变量表、操作数栈、动态链接、方法出口等信息。每一个方法从调用直至完成的过程,就对应着一个栈帧在虚拟机中从入栈到出栈的过程。 局部变量表存放编译期可知的基本数据类型(boolean、int、byte、short、double、long、float、char),对象引用(指向对象起始地址的指针或者是代表对象的句柄),returnAdress(指向字节码指令地址).。局部变量表所需的内存空间在编译期间完成分配。此区域发生的异常:StackOverflowError(线程请求的栈深度大于虚拟机允许的深度)、OutOfMemoryError(虚拟机栈动态扩展时无法申请到足够的内存)
本地方法栈:和 java虚拟机栈一样,区别是一个为执行Java方法服务、一个为为虚拟机使用到的Native方法服务
2、线程共享:
java堆(Heap):虚拟机管理的内存最大的一块。虚拟机启动时创建,作用存放对象实例。垃圾收集器管理的管理的主要区域,又称为GC堆。OutOfMemoryError(如果在堆中没有内存完成实例分配,并且堆无法扩展)
方法区(Method Area):存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。OutOfMemoryError(无法满足内存分配时)
·
OOM异常:
java堆溢出 (OOM :java heap space) :不断地创建对象达到限制。-Xms堆的最小值,-Xmx堆的最大值。他们设置一样可以避免堆自动扩展。
解决:1.检查堆参数和物理机内存比较是否可以调大;2.从代码上检查对象是否有生命周期过长情况
栈溢出:栈的容量-Xss参数设定
运行时常量池溢出(oom:PermGen space):-XX:PermSize -XX:MaxPermSize 限制方法区大小。