上海网站设计 企业,市场营销的主要应用领域,网站建设多长时间能学会,企业做网站哪家网站好一、快速扫盲
1. JVM是什么
JVM是Java Virtual Machine的缩写#xff0c;即咱们经常提到的Java虚拟机。虚拟机是一种抽象化的计算机#xff0c;有着自己完善的硬件架构#xff0c;如处理器、堆栈等#xff0c;具体有什么咱们不做了解。目前我们只需要知道想要运行Java文件…一、快速扫盲
1. JVM是什么
JVM是Java Virtual Machine的缩写即咱们经常提到的Java虚拟机。虚拟机是一种抽象化的计算机有着自己完善的硬件架构如处理器、堆栈等具体有什么咱们不做了解。目前我们只需要知道想要运行Java文件必须先通过一个叫javac的编译器将代码编译成class文件然后通过JVM把class文件解释成各个平台可以识别的机器码最终实现跨平台运行代码。 2. JDK、JRE、JVM之间的关系
JDK全称为Java Development Kit汉语为java开发工具包即所有有关java的东西都包含在里面比如运行环境JRE、java的核心代码、JVM等等。
JRE全称为Java Runtime Environment汉语为java运行环境即想要运行java文件必须先有java的环境才行jre就是提供了这么一个环境。
JVM上面已经提到了JVM它是java最核心的部分。
简单用一张图来理解这三个的关系 3. jvm的组成成分 不了解jvm的同学看到这张图后可能会有点懵逼不过没关系放这张图只是想让你了解jvm中有三块内容非常重要1.java代码如何执行2.内存如何管理3.线程资源如何利用脑袋里有个印象即可带着问题去学习。
4. 运行java文件的大概流程
想要运行java的源文件必须要经过javac编译器编译成.class文件也就是字节码文件。然后通过jvm中的解释器解释成特定机器上的机器码。每种机器上的解释器是不一样的我们经常用的也就是windows和linux系统这也是为什么java能够跨平台的原因。当一个程序从开始运行虚拟机就开始实例化多个程序运行就会存在多个虚拟机实例程序退出或者关闭虚拟机实例也将随之消亡多个虚拟机之间的数据是不共享的。
二、JVM运行时数据区
1. 运行时数据区域组成
虚拟机在执行java程序时会将自己管理的内存划分为几个区域每个区域都有自己的用途并且创建时间和销毁时间也不一样。在程序运行时的内存区域主要可以划分为五个分别是方法区、堆、虚拟机栈、本地方法栈、程序计数器。可以用下面的图来描述 2. Java堆
Java堆是java虚拟机所管理的内存中最大的一块是被所有线程都共享的内存区域。存在的唯一目的就是存放对象实例几乎所有的对象实例都在这里进行分配内存。不过目前随着技术的不断发展也并不是所有的对象实例都在堆中分配内存可能也存在栈上分配。由于所占空间大又存放各种实例对象因此java虚拟机的垃圾回收机制主要管理的就是此区域详细的垃圾回收方法以后会提到。JVM规范中规定堆可以处于物理上不连续的内存空间中只要逻辑上是连续的即可。并且可以通过-Xmx和-Xms来扩展堆的内存大小如果在堆中没有足够的内存为实例分配并且堆也无法在扩展时就会报OutOfMemoryError异常。
3 方法区
跟Java堆一样方法区是各个线程共享的内存区域此区域是用来存储类的信息(类的名称、字段信息、方法信息)、静态变量、常量以及编译器编译后的代码。JVM规范中并不区分方法区和堆只把方法区描述为堆的逻辑部分但是它却有一个别名叫做非堆(Non-Heap)目的就是与Java堆区分开。根据垃圾回收机制中分代回收的思想如果在HotSpot虚拟机上开发可以把方法区称为“永久代”(只是可以这么理解但实质是不一样的)垃圾回收机制在Java堆中划分一个部分称为永久代用此区域来实现方法区这样HotSpot的垃圾收集器就可以像管理Java堆一样管理这部分内存而不必为方法区开发专门的内存管理器。
运行时常量池
运行时常量池是方法区的一个部分class文件中除了有类的版本、字段、方法、接口等描述信息外还有一项信息是常量池用于存放编译期间生成的各种字面量和符号引用这部分内容会在类加载后进入方法区的运行时常量池中。Java 虚拟机对 Class 文件的每一部分(自然也包括常量池)的格式都有严格的规定每一个字节用于存储哪种数据都必须符合规范上的要求这样才会被虚拟机认可、装载和执行。
4. 程序计数器
虽然在上图中程序计数器的面积很大但实际上它是一块较小的内存空间可以看做当前线程所执行字节码的行号指示器。字节码解释器在工作中时下一步该干啥、到哪了就是通过它来确定的。大家都知道在多线程的情况下CPU在执行线程时是通过轮流切换线程实现的也就是说一个CPU处理器(假设是单核)都只会执行一条线程中的指令因此为了线程切换后能恢复到正确的执行位置每个线程都要有一个独立的程序计数器各条线程之间的计数器互不影响独立存储我们称这类内存区域为“线程私有”的内存。很明显程序计数器就是线程私有的。如果线程正在执行的是一个java方法程序计数器记录的是正在执行的虚拟机字节码指令地址如果执行的Native方法程序计数器记录的值为空(Undefined)此内存区域是java中唯一一个在java虚拟机规范中没有规定任何OutOfMemoryError情况的区域。
5. Java虚拟机栈
我们经常会把java内存粗糙的分为两个部分堆和栈Java虚拟机栈就是栈这一部分或者说是虚拟机栈中局部变量表部分。跟程序计数器一样虚拟机栈也是线程私有的它的生命周期跟线程相同。每个方法在执行的同时都会创建一个栈帧(Stack Frame)每个栈帧对应一个被调用的方法栈帧中用于存储局部变量表、操作数栈、动态链表、方法出口等信息。每一个方法从开始执行到结束就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。
局部变量表顾名思义他就是用来存储方法中的局部变量(包括在方法中生命的非静态变量以及函数形参)对于基本数据类型直接存值对于引用类型的变量存储指向该对象的引用。由于它只存放基本数据类型的变量、引用类型的地址和返回值的地址这些类型所需空间大小已知且固定所以当进入一个方法时这个方法需要在栈帧中分配多大的局部变量空间是完全可以确定的在方法运行期间也不会改变局部变量表的大小。
指向运行常量池的引用在方法执行过程中难免会使用到类中定义的常量因此栈帧中要存放一个指向运行时常量池的引用。
方法返回地址当一个方法执行结束后要返回到之前调用它的地方因此在栈帧中需要保存一个方法返回地址。
6. 本地方法栈
本地方法栈与虚拟机栈的功能非常的相似区别不过是虚拟机栈为虚拟机执行java方法服务而本地方法栈为虚拟机执行Native方法服务。有的虚拟机并不会区分本地方法栈和虚拟机栈比如Sun HotSpot虚拟机直接将两个合二为一。
7. 用一张图总结