虚拟机分区
程序计数器
较小的内存空间,可以看做当前线程所执行的字节码的行号指示器,字节码解释器工作时就是通过这个计数器的值来选取下一条需要执行的字节码指令,分支,循环,跳转,异常处理,线程恢复等基础功能都需要依赖这个计数器来完成
虚拟机栈
线程私有,生命周期与线程相同,每个方法被执行时都会同时创建一个栈帧,用于存储局部变量表,操作栈,动态链接,方法出口等信息 。通常说的栈就是指的虚拟机栈,或者说是虚拟机栈中的局部变量表部分,局部变量表所需的内存空间在编译期间完成分配,这个方法在帧中需要的大小是确定的,在运行期不会改变,如果请求深度过大或者无法申请到足够的内存会抛出异常,即StackOverflowError,OutOfMemoryError
本地方法栈
与虚拟机栈作用相似,虚拟机栈执行java方法,本地方法栈执行Native方法
java堆
所有线程共享的一块内存区域,在虚拟机启动时创建,唯一作用为存放对象实例,Java堆可以处于物理上不连续的内存空间中,只要逻辑上是连续的就可以,java堆也就GC堆,里面可以细分为新生代和老年代,大小可以扩展,利用-Xmx 和-Xms控制,如果堆内无内存可以分配也无法拓展是,将会抛出OutOfmemeryError
方法区
与java堆一样,是各个线程共享的内存区域,用于存放已被虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码等数据,垃圾收集器在这个区域很少出现,方法区被称为永久代,数据并非不会被回收,这个区域回收主要针对常量池的回收和对类型的卸载
运行时常量池:是方法区的一部分,class文件中出了有类的版本、字段、方法、接口等描述等信息外,还有一项是常量池,用于存放编译期生成的各种字面量和符号引用,这部分内容将在类加载后存放到方法去的运行时常量池中
直接内存
非虚拟机运行时数据区的一部分。NIO(new input/output)类,有一种基于通道(channel)与缓冲区(buffer)的I/O方式,可以使用native函数库直接分配堆外内存