JVM(上)

本文详细介绍了JVM的工作原理,包括类加载器的双亲委派机制、内存模型的各分区(如PC寄存器、方法区、栈)及其作用,以及JVM的内存管理和调优,如堆与方法区的处理、GC算法和堆溢出、栈溢出的问题。同时,探讨了JVM如何通过沙箱安全机制保护系统资源,以及Native方法与本地方法栈的关系。
摘要由CSDN通过智能技术生成
  • 谈谈对JVM的理解
  • JVM中,类加载器的理解
  • JVM的内存模型和分区
  • 什么是OOM,什么是栈溢出StackOverFlowError,怎么分析
  • JVM常用调优参数有哪些
  • 内存快照怎么抓取,怎么分析Dump文件
  • GC算法有哪些

JVM的位置

在这里插入图片描述

JVM的体系结构

在这里插入图片描述

JVM调优基本在方法区和堆处理

类加载器

作用:加载.class文件

如果某类还未被加载到内存中,则JVM会通过加载、连接、初始化3个步骤来对该类进行初始化。

  • 加载指的是将类的class文件读入到内存,并为之创建一个java.lang.Class对象。
  • 连接阶段负责把类的二进制数据合并到JRE中。
  • 初始化是为类的静态变量赋予正确的初始值。

在这里插入图片描述

双亲委派机制

如果一个类加载器收到了类加载请求,它并不会自己先去加载,而是把这个请求委托给父类的加载器去执行,

如果父类加载器还存在其父类加载器,则进一步向上委托,依次递归,请求最终将到达顶层的启动类加载器,

如果父类加载器可以完成类加载任务,就成功返回,

倘若父类加载器无法完成此加载任务,子加载器才会尝试自己去加载。

根类加载器←扩展加载器←用户加载器←自定义的类加载器

沙箱安全机制

将 Java 代码限定在虚拟机(JVM)特定的运行范围中,并且严格限制代码对本地系统资源访问,通过这样的措施来保证对代码的有效隔离,防止对本地系统造成破坏。

沙箱主要限制系统资源访问,系统资源包括CPU、内存、文件系统、网络。

不同级别的沙箱对这些资源访问的限制也可以不一样。

Native

使用Native关键字说明java作用范围达不到,需要调用底层c语言的库。

进入本地方法栈,调用本地方法接口(JNI)

JNI作用:扩展java的使用,融合不同的编程语言为java所用

PC寄存器

PC寄存器是线程私有的指针,用来存储指向下一条指令的地址,也就是即将要执行的指令代码。由执行引擎读取下一条指令。

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

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

  3. 任何时间一个线程都只有一个方法在执行,也就是所谓的当前方法。程序计数器会存储当前线程正在执行的java方法的JVM指令地址;如果实在执行native方法,则是未指定值(undefined),因为程序计数器不负责本地方法栈。

  4. 它是程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器来完成

  5. 字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令

  6. 它是唯一一个在java虚拟机规范中没有规定任何OOM(Out Of Memery)情况的区域,而且没有垃圾回收

1.使用PC寄存器存储字节码指令地址有什么用呢(为什么使用PC寄存器记录当前线程的执行地址呢)

(1)多线程宏观上是并行(多个事件在同一时刻同时发生)的,但实际上是并发交替执行的

(2)因为CPU需要不停的切换各个线程,这时候切换回来以后,就得知道接着从哪开始继续执行

(3)JVM的字节码解释器就需要通过改变PC寄存器的值来明确下一条应该执行什么样的字节码指令

所以,众多线程在并发执行过程中,任何一个确定的时刻,一个处理器或者多核处理器中的一个内核,只会执行某个线程中的一条指令。这样必然导致经常中断或恢复,如何保证分毫无差呢?每个线程在创建后,都会产生自己的程序计数器和栈帧,程序计数器在各个线程之间互不影响。

2.PC寄存器为什么会设定为线程私有?

(1)我们都知道所谓的多线程在一个特定的时间段内只会执行其中某一个线程的方法,CPU会不停滴做任务切换,这样必然会导致经常中断或恢复,如何保证分毫无差呢?

(2)为了能够准确地记录各个线程正在执行的当前字节码指令地址,最好的办法自然是为每一个线程都分配一个PC寄存器,这样一来各个线程之间便可以进行独立计算,从而不会出现相互干扰的情况。

方法区

线程共享的内存区域,存储已被虚拟机加载的类信息(构造方法,接口)、常量、静态变量,静态代码块、常量池,即时编译器(JIT Compiler)编译后的代码数据等。

这个区域的内存回收目标主要是针对常量池的回收和对类型的卸载。

栈内存,主管程序运行,生命周期和线程同步。但资源占满就栈溢出。线程结束释放栈内存,不存在垃圾回收。

栈溢出是指向栈中写入了超出限定长度的数据,溢出的数据会覆盖栈中其它数据,从而影响程序的运行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值