JVM学习笔记

一、狂神说

1、jvm的位置

jvm也是c写的,java是c和c++写的
在这里插入图片描述

2、jvm的体系结构

在这里插入图片描述
拿一段最简单的代码来分析,每个部分的存放位置如下图:
在这里插入图片描述
简化后的示意图:
在这里插入图片描述

3、类加载器之双亲委派机制

先了解一个.class加载的工作步骤:
在这里插入图片描述
在这里插入图片描述

案例解释上图步骤:

package javaDemo;

public class CarTest {
	public int age;

	public static void main(String[] args) {
//		// new一个对象
		CarTest carTest = new CarTest();
		CarTest carTest2 = new CarTest();
		CarTest carTest3 = new CarTest();
		System.out.println(carTest.hashCode());
		System.out.println(carTest2.hashCode());
		System.out.println(carTest3.hashCode());
		// 获取这个对象的类
		Class<? extends CarTest> class1 = carTest.getClass();
		Class<? extends CarTest> class2 = carTest2.getClass();
		Class<? extends CarTest> class3 = carTest3.getClass();
		System.out.println(class1);
		System.out.println(class1.hashCode());
		System.out.println(class2.hashCode());
		System.out.println(class3.hashCode());
		// 获取加载这个类的类加载器
		ClassLoader classLoader = class1.getClassLoader();
		ClassLoader classLoader2 = class2.getClassLoader();
		ClassLoader classLoader3 = class3.getClassLoader();
		System.out.println(classLoader.hashCode());
		System.out.println(classLoader2.hashCode());
		System.out.println(classLoader3.hashCode());
	}
}
/*
输出结果:
		366712642  //每个对象是独立的,new一个就是一个对象
		1829164700
		2018699554
		class javaDemo.CarTest //但类都是一样的
		705927765
		705927765
		705927765
		1943105171    //类加载器也是一样的
		1943105171
		1943105171
*/

清楚了上图中.class加载过程,再细说类加载器是怎样加载类的。
再看一个java案例:

package javaDemo;

public class CarTest {
	public int age;

	public static void main(String[] args) {
		// new一个对象
		CarTest carTest = new CarTest();
		// 获取这个对象的类
		Class<? extends CarTest> class1 = carTest.getClass();
		System.out.println(class1);
		// 获取加载这个类的类加载器
		ClassLoader classLoader = class1.getClassLoader();
		System.out.println(classLoader);
		// 获取加载这个类的父加载器
		ClassLoader parent = classLoader.getParent();
		System.out.println(parent);
		// 获取加载这个类的父加载器
		ClassLoader grantparent = parent.getParent();
		System.out.println(grantparent);
	}
}
/*
输出:
	class javaDemo.CarTest
	sun.misc.Launcher$AppClassLoader@73d16e93
	sun.misc.Launcher$ExtClassLoader@15db9742
	null  //注意:这个null不是说不存在,而是说明了Boot加载器调用不到,因为是c\c++写的
*/

分析:由以上运行结果可知,类加载器加载类的时候是遵循双亲委派机制的,所谓双亲委派机制,也就是说,你写的类、不论是自定义的Student还是自己写一个与java基本类型完全一样的java.lang.String,类加载机制的步骤:
1、类加载器收到类加载的请求后,会将这个加载请求委托给父类、父类委托给祖类加载器
2、然后祖类就开始找,祖类找不到后抛出异常,再去通知父类加载器找,父类加载器找不到也会抛出异常,通知应用加载器找,也就是会先去rt.jar中找Bootstap加载器,再去exc找Extension ClassLoader,最后才是应用程序AppClassLoader,
3、如果应用加载器也找不到,就会报Class Not Found
在这里插入图片描述
在这里插入图片描述
自定义加载器可继承ClassLoader类去实现

4、沙箱安全机制

了解即可
在这里插入图片描述

5、native与本地方法栈(Native Method Stack)

一旦被native修饰,就说明java的作用范围达不到了,就会去调用c语言的库!也就是进入本地方法栈,然后调用本地方法接口,也就是JNI(java native interface)。JNI是为了扩展java的使用,融合不同的编程语言为java所用。

6、PC寄存器(程序计数器)

在这里插入图片描述
在这里插入图片描述

  • pc寄存器的相关面试题
  1. 使用PC寄存器存储字节码指令有什么用?或者说,为什么使用PC寄存器记录当前线程的执行地址呢?
    答:因为CPU需要不停的切换各个线程,这时候切换回来的时候就得知道接着从哪开始继续执行。JVM的字节码解释器就要通过改变PC寄存器的值来明确下一条应该执行什么样的字节码指令

7、方法区

方法区在jdk1.8之前也叫永久代,现在改名元空间
在这里插入图片描述
在这里插入图片描述

8、栈(先进后出)

  • 主要包含局部变量表、操作数栈、方法返回地址、动态链接和一些附加信息。如下图
    在这里插入图片描述

  • 是什么?
    在这里插入图片描述

存放:基本类型+对象的引用+实例的方法

  • 栈运行原理:栈帧,如下图stack1、stack2
    在这里插入图片描述

9、堆

堆调优、jvm调优参照另一篇博客此博客第一阶段的第九条
小案例之OOM故障排除之Jprofiler工具的使用
在这里插入图片描述
1、idea下载Jprofiler插件
2、电脑安装Jprofiler客户端,可直接百度搜索
3、写一个报OOM的程序,注意此时如果想使用try...catch...捕获OOM要catch(Error e),因为OOM是error,不是exception
4、运行时修改jvm运行参数初始内存1m(默认为服务器内存的1/64),最大内存8m(默认为服务器内存的1/4):-Xms1m -Xmx8m -XX:+HeapDumpOnOutOfMemoryError
在这里插入图片描述
在这里插入图片描述
5、用Jprofiler打开这个文件,要使用Jprofiler来监控分析
在这里插入图片描述

10、GC:垃圾回收机制

GC参照另一篇博客此博客第一阶段的第八条

11、学习视频:

【狂神说Java】JVM快速入门篇

二、尚硅谷

1、JVM的整体结构

在这里插入图片描述
类装载器子系统又分为三步,loading、linking、initialization
在这里插入图片描述

2、JVM的架构模型

有两种,其中HotSpot VM是基于栈的指令集架构
在这里插入图片描述

3、Java虚拟机都有哪些

在这里插入图片描述

4、静态变量(类变量)、实例变量和局部变量的对比

静态变量:在方法区里,类加载器子系统初始化时,在linking阶段给类
变量默认赋值,initialization阶段给类变量显式赋值即静态代码块赋值

实例变量:随着对象的创建,会在对空间中分配实例变量空间,并进行默认赋值

局部变量:在使用前必须显式赋值,否则编译不通过,局部变量表(在栈中)中的变量也是重要的垃圾回收根节点,
只要被局部变量表中直接或间接引用的对象都不会被回收

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值