JVM的运行过程
java 文件通过javac工具生成class文件,然后通过类加载器加载在运行时数据区,运行时数据区是JVM 所管理的内存,JVM 就是把class 翻译成机器码,是一个基于栈的解释器。
运行时数据区
运行时数据区会把管理的内存分成若干个区域,总体分为线程私有和线程共享两个部分:
1)线程私有:虚拟机栈、本地方法栈、程序计数器
2)线程共享:堆内存、方法区
线程私有
每一个线程都会有一个栈和一个程序计数器
1)程序计数器:
Java虚拟机中多线程采用时间片轮转的方式实现,一个处理器(如果是多核处理器就是一个内核)同一时间只能被一个线程使用,同一时间只能执行一个线程的指令,当时间片用完,处理器就要交给别的线程使用,为了下一次轮到自己使用处理器是能够接着执行现在的指令,使用一个计数器来记录,从本质来看,程序技术器就是一块比较小的内存空间,不会被回收
2)虚拟机栈:
虚拟机栈是线程私有的,每创建一个线程,虚拟机就会为这个线程创建一个虚拟机栈,虚拟机栈表示Java方法执行的内存模型,每调用一个方法就会为每个方法生成一个栈帧(Stack Frame),用来存储局部变量表、操作数栈、动态链接、方法出口等信息。每个方法被调用和完成的过程,都对应一个栈帧从虚拟机栈上入栈和出栈的过程。虚拟机栈的生命周期和线程是相同的”。
3)本地方法栈
本地方法栈和上面的介绍的虚拟机栈基本上相同,只不过是针对(native)本地方法的,有些虚拟机已经将两个合二为一(比如HotSpot)
栈帧:每个方法执行都会产生一个栈帧,栈帧里面有局部变量表,操作数栈,动态链接,返回地址,具体如下图所示
线程共享
堆:
堆事线程共享的,我们程序运行过程中会产生一个个对象,就是存储在堆内存里的,几乎所有的对象实例都是在堆里面进行分配的,因此他是Java的垃圾回收器(GC)管理的主要区域,也称作GC堆,因为事内存共享的,所以在此区域的对象被多个线程同时访问时需要考虑线程安全问题。按照对象存储的时间都不同,堆中的内存可以分为新生代和老年代两种,其中新生代又被划分为Eden 和Survivor 区,一个对象熬过多次垃圾回收,还没有被回收就会由新生代转入老年代,老年代是最不容易回收的
方法区:
方法区是JVM 规范中规定的一块区域,方法区主要用来存储类信息、常量、静态变量等信息,这个区域也是线程共享的。jdk1.7之前使用的是"永久区"来实现方法区,1.8 以后用的是一个叫"元空间"的实现方式
以上基本上就是JVM 的内存模型