JVM学习笔记

JVM是什么 定义:

JVM是Java Virtual Machine(Java虚拟机)的缩写,是一台执行Java字节码的虚拟计算机,它拥有独立的运行机制。

可以将JVM理解为是一个运行字节码的平台。

作用:

提供Java的运行环境

加载代码、验证代码、执行代码

垃圾回收

为什么要学习JVM

首先,作为一名Java程序员,通过学习JVM,能让你对Java这门语言有更深刻的理解,更加了解底层程序的执行过程;

其次,我们都知道Java语言,是一个能自动回收内存的语言,这个特点大大方便了我们程序员。但是,也正因为这个特点,如果程序发生内存泄漏、内存溢出等情况的时候,而我们又不了解底层的垃圾回收机制的话,就会给我们解决问题带来很大的麻烦。

进入正题

JVM架构图-简图

JVM学习笔记

JVM家族

鼻祖:Sun Classic、Exact VM

主流:HotSpot VM

次之:BEA JRockit、IBM J9 VM

其他:BEA Liquid VM、Azul VM...

类加载器子系统 作用

类加载子系统负责从文件系统或者网络中加载class文件,class文件在文件开头有特定的标识。

ClassLoader只负责class文件的加载,至于它是否可以运行,则由执行引擎来决定。

类加载过程

加载——>链接——>初始化——>使用——>卸载

链接包括三个阶段(验证、准备、解析)

类加载器分类

启动类加载器(Bootstrap ClassLoader)

扩展类加载器(Extension ClassLoader)

系统类加载器(Application ClassLoader)

自定义类加载器(User Defined ClassLoader)

类加载机制

双亲委派机制

定义: 当一个类加载器收到了类加载的请求时,它首先不会自己去加载,而是会把这个请求交给父类加载器,如果父类加载器还有父类,就会一直往上传,直至传递到启动类加载器,如果父类加载器不能加载,才由子类加载器进行加载。

好处:

避免类重复加载

保护程序安全,防止核心API被随意修改

自定义类:java.lang.String(该类不会被加载)

自定义类:java.lang.Tang(报错:阻止创建 java.lang开头的类)

保证核心API的访问权限

内存模型(运行时数据区)

JVM学习笔记

运行时数据区是JVM中非常重要的一部分,由程序计数器、虚拟机栈、本地方法栈、堆、方法区组成。

程序计数器(Program Counter Register)

介绍
JVM中的程序计数寄存器(Program Counter Register)中,Register的命名起源于CPU的寄存器,寄存器存储指令相关的现场信息。

它是一块很小的内存空间,几乎可以忽略不计。也是运行速度最快的存储区域。

在JVM规范中,每个线程都有它自己的程序计数器,是线程私有的,生命周期与线程的生命周期保持一致。

任何时间一个线程都只有一个方法在执行,也就是所谓的当前方法。程序计数器会存储当前线程正在执行的Java方法的JVM指令地址;或者,如果是在执行native方法时,则是未指定值(undefined)。

它是程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器来完成。字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令。

它是唯一一个在Java虚拟机规范中没有规定任何OOM情况的区域。

作用
程序计数器用来存储指向下一条指令的地址,也就是即将要执行的指令代码。由执行引擎读取下一条指令。

虚拟机栈(Stack)

概述
Java虚拟机栈是线程私有的,用于存储栈帧。每个方法在执行的同时都会创建一个栈帧,用于存储局部变量表、操作数栈、动态链接、方法出口等。每一个方法从调用直至方法执行完成的过程,就对应着一个栈帧在虚拟机中从入栈到出栈。

作用
主管Java程序的运行,它保存方法的局部变量、部分结果,并参与方法的调用和返回。

栈中发生的异常有
StackOverflowError、OutOfMemoryError

如果线程请求分配的栈容量超过虚拟机栈允许的最大容量,Java虚拟机将会抛出一个stackoverflowError 异常。

如果虚拟机栈可以动态扩展,并且在尝试扩展的时候无法申请到足够的内存,或者在创建新的线程时没有足够的内存去创建对应的虚拟机栈,那么Java虚拟机将会抛出一个outofMemoryError异常。

// 演示栈中的异常:StackOverflowError public class StackErrorTest { private static int count = 1; public static void main(String[] args) { System.out.println(count++); main(args); } }

设置栈内存大小
我们可以使用参数 -Xss选项来设置线程的最大栈空间,栈的大小直接决定了函数调用的最大可达深度

-Xss256k

本地方法栈(Native Method Stack)

概述
本地方法栈与虚拟机栈类似,唯一的区别就是:Java虚拟机栈用于管理Java方法的调用,而本地方法栈用于管理本地方法的调用。

注:本地方法是使用C语言实现的

堆(Heap)

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpwsjy.html