(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 来引用和操作堆外内存空间,其实很多技术都会用这种方式,因为有一些场景下,堆外内存分配可以提升性能。