(JDK1.7)
JVM识别的编译后的字节码文件
-
程序计数器
针对每个线程都有独立的计数器,记录当前这个线程执行到哪一条字节码指令了 -
Java虚拟机栈
- JVM必须有一块区域来保存每个方法的内的
局部变量等等数据,每个线程都有自己的Java虚拟机栈,对应被调用的每个方法都会有一个栈帧,方法执行完毕后就会把相应的方法栈帧从栈里剔除 - 调用执行任
何方法的时候,都会给方法创建栈帧然后入栈。而在栈帧里存放了这个方法对应的局部变量之类的数据,包括这个方法执行的其他相关的信息,方法执行完毕之后就出栈。
-
Java堆内存
存放我们在代码中创建的各种对象
例子:
Java堆内存区域里会放入类似Student的对象,然后方法的栈帧的局部变量表里,这个引用类型的“student”局部变量就会存放Student对象的地址。 -
方法区/Metaspace
JDK 1.8以后,这块区域的名字改了,叫做“Metaspace”。可以认为是“元数据空间”这样的意思,这里当然主要其实还是存放我们自己写的各种类相关的信息(对于习惯在HotSpot虚拟机上开发和部署程序的开发者来说,很多人愿意把方法区称为“永久代”(Permanent Generation))作用:平时用到的各种类的信息,都是放在这个区域里的,还会有一些类似常量池的东西放在这个区域里。(主要存放已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据) -
本地方发栈
在调用这种native(C语言)方法的时候,就会有线程对应的本地方法栈,这个里面也是跟Java虚拟机栈类似的,也是存放各种native方法的局部变量表之类的信息 -
堆外内存:
还有一个区域,是不属于JVM的,通过NIO中的allocateDirect这种API,可以在Java堆外分配内存空间。然后通过Java虚拟机里的 DirectByteBuffer 来引用和操作堆外内存空间,其实很多技术都会用这种方式,因为有一些场景下,堆外内存分配可以提升性能。