目录
总览
JVM的内存结构
执行引擎把字节码翻译成机器码。
计数器
计数器就为线程服务的。一个栈对应一个线程,但每个线程的时间不是无限的,一般来说每个线程都有一个时间片;时间片用完之后,就会切换到下一个线程。而线程重新回来之后,代码应该从哪一行开始继续进行,就要看计数器记录的数字。因此每个线程对应每个虚拟机栈对应每个计数器,是一对一对一的关系。
英文叫做(程序 计数 register),后缀是寄存器,计数器是在寄存器当中实现的。因为计数器需要频繁调用,而寄存器读起来最快。
栈
除了这个虚拟机栈之外,还有一个本地方法栈。栈内存是Java的一种内存,主要是用来执行程序用的,当JVM栈中有的命令做不到时,就调用本地方法栈。
主程序压入栈,主程序调用的程序再进栈,就这样一层压一层。每一个方法在栈中叫做栈帧。当顶层方法执行完毕之后,则自动出栈。所以栈不需要垃圾回收,自己用完就扔掉了。
堆
堆内存是是Java内存中的一种,它的作用是用于存储Java中的对象和数组,当我们new一个对象或者创建一个数组的时候,就会在堆内存中开辟一段空间给它,用于存放。
堆的数据结构是用数组实现的二叉树。由于堆的数据结构无法做到用完之后就知道要把这个对象回收掉,所以堆整体需要垃圾回收(GC)。
为了实现垃圾回收,堆中内存又分成了新生代和老年代,新时代中又包含Eden(伊甸园)和survivor1和survivor2。
方法区
方法区也就是最新的元空间。
方法区(Method Area)与上面讲的Java堆一样,都是各个线程共享的,它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
JDK1.7之前的方法区是放在堆中的,并专门划分一个空间叫做永久代给方法区使用。但由于永久代总是OutOfMemory,所以JDK1.8之后将永久代剥离开来并把它放在系统内存当中,并改名叫元空间。