Java运行时数据区域
在一个Java程序运行的时候,Java虚拟机在看不到的地方工作着,它主要是管理内存的而且是自动的,所以平常并不需要人为干预,虽然看不见它但是必须去了解JVM,因为在遇到内存泄漏和内存溢出的时候如果不知道它的运作原理那么就干等着,无从下手。
如图,JVM管理的内存包括这几个数据区域
上面这个就是JVM内存模型, 有五个区域,而在这些区域中有的又能在自身基础上划分更细致的区域。
方法区:是进程中各个线程共享的内存区域,存放着被JVM加载的各种信息,像类型,常量啊什么的...
虚拟机栈:这个东西是线程私有的,所以它随线程生而生,灭而灭,还有两个和线程同生共死的区域是程序计数器和本地方法栈。一看到栈就肯定能想到这里面是放着局部变量的。一个方法从被调用到执行完毕就对应着一个栈帧从入栈到出栈的过程。
本地方法栈:一看到本地就知道这个里面放着本机操作系统的各种方法,它为JVM使用到的本地方法服务,运行时常量池就是它的一部分,用于存放编译期间生成的各种字面量与符号引用,当它无法再申请内存时会抛出OutOfMemoryError异常。
堆:它很重要,因为所有Java程序new的对象都在这里面放着,因为对象的内存分配都是在堆上完成的,而Java又是一门面向对象对象对象语言,所以它真的很重要,正因为所有对象都在它这放着,所以它的空间相对来说比较大,空间大了可用的地方就多了,所以在堆中又开辟了几个区域,分别是,新生代区域,老年代区域,永久代区域,新生代区域放的就是刚new的对象,如果经过了一定次数的GC后它还没有die,那么它就晋升到老年代区域,而永久代区域里面存放的是一直要使用的对象。
程序计数器:顾名思义,它就是记录程序语句的,像if,while,for,try..catch...finally等,只不过现在的程序变成了字节码。上面说到了,这个程序计数器也是随线程同生共死的,其实意思就相当于每条线程都有一个属于自己的独立的程序计数器,JVM读到的数据是经过javac过后的.class文件,当线程执行Java的方法的时侯,它记录的就是这个字节码指令对应的地址。