声明: 《深入理解Java虚拟机 JVM高级特性与最佳实践 第2版》。以下内容来自书中第二章。
1. JVM概述
JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。
引入Java语言虚拟机后,Java语言在不同平台上运行时不需要重新编译。Java语言使用Java虚拟机屏蔽了与具体平台相关的信息,使得Java语言编译程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行 ——百度百科
可以将JVM理解成一台机器,这个机器可以用来执行java程序。这样java代码就可以实现一次编写,到处运行了。在不同的机器上配置相应的JVM即可。 在机器上,JVM实际上也是一个程序。
2. JVM内存分配
2.1 运行时数据区域
根据《Java 虚拟机规范(Java SE 7 版)》的规定,Java虚拟机所有管理的内存将会包括以下几个运行时数据区域,如下图所示:
简单说一下各个数据区域的作用:
线程私有的数据区域:线程私有区域都是与线程同生共死的,即生命周期与线程相同。
线程共享的数据区域:生命周期与JVM相同
**程序计数器:**每个线程都有的"小本本",线程不是连续不断工作的。再次运行时它就要看看“小本本”里的内容才知道自己该从什么地方继续做下去。
在JVM中的多线程是通过轮流切换的方式执行的,在任何时刻一个CPU(相当于多核CPU的一个核)只能运行一个线程。如果某个进程的某个线程占用CPU很长的时间,那么其他的线程会一直等下去吗?为了让用户不会有:”哇!我这个傻X计算机怎么这么卡啊!“的错觉。CPU就给了每个线程分配了一个CPU时间,当线程的CPU时间用完之后,他就会把CPU的计算资源让出来给其他线程,等到下次轮到它的时候它再执行。所以每个线程都需要一个私有的程序计数器来记录自己执行到哪儿了。它实际可以理解成一个记录程序执行的字节码的行号的指示器。 计数器只会占用内存中很小的一部分空间。
Java虚拟机栈:程序员口中常说的“堆栈”大抵说的就是这个区域中的局部变量表。虚拟机栈是用来描述Java方法执行时的内存模型。这种描述是通过存储方法开始执行(入栈)到方法结束(出栈)过程中的局部变量表、操作数栈、动态链接及方法的出口等信息来是实现的。方法在执行时会创建一个栈帧,用来存储前面说的各种信息,方法完成,栈帧出栈。
局部变量表存放了编译期间可知的各种基本数据类型和引用类型,以前上课的时候说的堆栈的时候,老师可能会画这样的一张图:
Variable | Value |
---|---|
variable1 | 13 |
variable2 | 2.3 |
variable3 | ‘a’ |
variable4 | true |
z |