JVM-基础知识
什么是JVM
- JVM是一种跨语言的平台,任何语言只要能编译成.class文件都可以被JVM运行。
- JVM只和.class文件有关系,和Java语言没关系。
- JVM是一种虚拟机规范。
java文件是如何交给JVM执行的
JVM的常见实现
- HostStop:Oracle官方
- 另外还有IBM的J9、Microsoft VM、TaoBaoVM、azul zing(收费)。
堆、栈
- 栈和堆是内存中的进程的结构
- 一个线程一个栈,这个线程中的每个方法是一个栈贞
- 栈中存储的是堆中内存的地址
- 栈内存空间在方法弹栈后自动消失,而堆内存空间需要手动管理,这就导致栈贞弹出时候,但是其指向堆中的内存空间是无法被释放
栈帧
每个方法对应一个栈帧, 其中包括:
- Local Variable Table:局部变量表。存储方法中的局部变量,包括形参
- Operand Stack:操作数堆栈
- Dynamic Linking:指向性JVM运行时常量池
- return address: 方法返回值地址
栈上分配和线程本地分配(TLAB)
触发的情况
- 线程私有且小对象
- 无逃逸,即方法内部的变量,无方法外部引用
- 标量替换,即可以用少了的基本数据类型、引用类型等可以代替整个对象
线程本地分配(TLAB)
全称ThreadLocal Allocation Buffer,在edne区大约占用1%的内存归线程独有空间,多线程下不必争抢堆内存空间,提高效率。
JVM运行时数据区(RunTimeDateArea)
包括以下几部分:
- PC-程序计数器:存放指令的位置,cup执行就是不停的在PC中取指令执行,直到指令被执行完,每个线程一个。
- JVM stacks-JVM的栈:存放栈帧,每个线程一个
- native method stacks-本机方法栈: C/C++中的栈,本地方法栈,每个线程一个
- heap-堆:线程共享
- method area-方法区: 包括JVM运行时常量池,线程共享
- DirectMemory-直接内存区:直接内存区,JDK1.4后新增,可直接访问内核空间内存,NIO实现零拷贝
JVM内存关系
- 堆内存:分为年轻代,老年代
- 非堆内存:只包含永久代,即方法区的实现,存储的是程序运行时长期存活的对象,比如类的元数据、方法、常量、属性等。
- 1.8之前方法区的实现为PermGen,jdk1.8开始方法区的实现为MetaSpace。
- 在jdk1.8废弃了永久代,使用元空间(MetaSpace)取而代之,元空间存储的对象与永久代相同,区别是:元空间并不在jvm中,使用的是本地内存。
- 在jdk1.8,字符串常量池已经从永久代移动到了堆中