Java内存划分

Java虚拟机在执行Java程序的过程中会把它所治理的内存划分为若干个不同的数据区域,如下图

一、程序计数器

程序计数器(Program Counter Register)是一块很小的内存空间,就像计算机组成原理的PC寄存器,它能够看作以后线程所执行的字节码的行号指示器,解释器通过扭转计数器的值来实现分支、循环等操作。为了避免线程切换之后找不到原来执行的地位,每个线程都独自领有一个程序计数器,能够称这类内存为“线程公有”内存。

二、Java虚拟机栈

它和程序计数器一样是线程公有的,当每个办法执行的时候Java虚拟机都会产生一个栈帧(Stack Frame),栈帧中存储了局部变量表(注:进入一个办法的时候,办法所须要的局部变量大小是确定的,不会再扭转)、操作数栈、动静链接、办法进口等信息)
在Java虚拟机创立完栈帧之后就会把它入栈到虚拟机栈中,当执行结束后就将栈帧出栈,因而当有限递归时,会发明大量的栈帧进入到虚拟机栈中,就会产生StackOverflow异样

public static  void stackLeak(){    stackLeak();}public static void main(String[] args) {    stackLeak();}

运行后果为

除了上述情况,当应用的Java虚拟机容许动静扩大虚拟机栈的时候,就会始终申请内存扩大虚拟机栈,直到无奈申请到足够的内存,这时候便会产生OutOfMemoryError异样

三、本地办法栈

本地办法栈与虚拟机栈十分相似,虚拟机栈为Java办法提供服务,而本地虚拟机栈为本地办法服务,在栈深度溢出的时候也会产生StackOverflowError或者OutofMemoryError

四、Java堆

Java堆与虚拟机栈不同,它是所有线程共享的一片区域,它只有一个性能就是寄存对象实例,咱们平时应用的对象变量外面寄存的则是对象地址,它指向堆中的对象实例。
始终循环生成新的对象便会造成Java堆溢出,而产生OutOfMemory异样

static class OOMObject{}public static void main(String[] args) {    //应用list放弃援用,避免GC回收对象    List<OOMObject> list= new ArrayList<OOMObject>(); while(true){        list.add(new OOMObject()); }}

应用虚拟机参数-Xms20m -Xmx20m限度堆大小为20m不可扩大,运行上述程序后后果为

能够看出始终产生新对象,就会占满堆内存

五、办法区

办法区与Java堆一样,也是各个线程所共享的区域,它存储了每一个类的构造信息(Class文件),例如运行时常量池,字段和办法数据,构造函数和一般办法的字节码内容,还包含一些在类,实例,接口初始化时用到的非凡办法。
当限度办法区大小并且一直加载类文件的时候,办法区就会溢出,从而产生OutOfMemory异样