JVM主要由4部分组成:
1.类加载器(ClassLoader):在JVM启动时或者类运行时,将需要的class文件加载到JVM中。
2.Java内存区:在JVM运行时操作系统分配的内存区。运行时内存区主要可以分为5个部分:
- 方法区(MethodArea):用于存储类结构信息的地方,包括常量池、静态变量、构造函数等。虽然JVM规范把方法区描述为堆的一个辑部分,但是他还有一个别名non-heap(非堆)。方法区还包含一个运行时常量池。
- Java堆(Heap):存放实例或对象的内存区域。
- Java栈(Stack):Java栈总是跟线程关联在一起,每当创建一个线程,JVM就会给它创建一个对应的Java栈,这个Java栈中又包含了多个栈帧,每运行一个方法就创建一个栈帧,用于存储局部变量表、操作栈、方法返回等。每一个方法从调用到执行完毕这一过程,就对应一个栈帧在Java栈中从入栈到出栈的过程。所以Java栈是现成有的。
- 程序计数器(PCRegister):用于保存当前线程执行的内存地址。因为JVM程序是多线程执行,也就是轮流切换执行,因此为了切换回来还能恢复到原来状态。所以需要一个独立计数器,记录中断的位置,因此程序计数器是线程私有的。
- 本地方法栈(Native MethodStack):和Java栈作用差不多,主要是为了让JVM可以使用本地服务。
3.执行引擎:负责执行class文件中包含的字节码指令。
4.本地方法接口:主要是调用C或者C++实现的本地方法和回调结果。
创建线程影响哪块内存?
每当有线程被创建,JVM都要为其在内存中分配虚拟机栈和本地方法栈,记录调用方法的内容,分配程序计数器记录线程执行位置。这就是创建线程所消耗的内存代价。
2.JVM的内存模型的理解
什么是JMM
Java内存模型,简称JMM。JMM定义了Java虚拟机(JVM)在计算机内存中的工作方式。JVM是整个计算机的虚拟模型,所以JMM是属于JVM的。
1.Java线程之间的通信总是隐式进行的,并采用的是共享内存模型。这里的共享内存模型就是指JMM,JMM决定了一个线程对共享变量的写入何时对另一个线程可见。
2.从抽象角度来看,JMM定义了主内存和线程之间的抽象关系:线程的共享变量存储在主内存,每个线程都有一个私有的本地内存,本地内存中存储了该线程已读/写的共享变量副本。
3.本地内存实际不存在,只是JMM的一个抽象概念。它涵盖了缓存,写入缓冲区,寄存器以及其他硬件和编译器优化。
总之,JMM就是一组规则,这组规则意在解决并发编程中可能出现的线程的安全问题,并提供内置解决方案及其外部可使用的同步手段(synchronized/volatile),确保了程序执行在多线程环境中应有的原子性、可见性、有序性。
参考文章:https://juejin.im/post/5e5c5c52f265da575f4e7558#heading-187