1.2019年周阳老师JVM·第一部分

JVM架构图

常见的虚拟机面试题:主要是考淘宝的大神周志明写的那本书
在这里插入图片描述

JVM体系结构概述

在这里插入图片描述
扩展:JNI–java调用底层硬件,android还在用。
在这里插入图片描述
对于这张图,做一个知识链接,runtimeException是从运行时数据区抛出来的。

类装载器

在这里插入图片描述
方法区:放类的描述信息,就是放模板的地方。
classLoader有多种(粗说三个,细说四个,下面介绍)。类装载器之前是class(小写),装载之后是Class。也就是下面这个类。
在这里插入图片描述
特定的文件标示是java的图标:cafe babe
在这里插入图片描述

类加载器都有哪些?

在这里插入图片描述
在这里插入图片描述
系统自带的类,比如object,打印类加载器是null,实际上自带的类是被bootstrap classload加载的,但是你打印不出来。bootstrapclassloader是顶级的类加载器,不再有父类了。所有你一安装jdk就能用的,都是由bootstapclassloader加载。是安装路径lib目录下的rt.jar,也就是runtime.jar,运行时需要的jar包。可以打开rt.jar看一下,如下:
在这里插入图片描述
在这里插入图片描述
如果是自己编写的类,走的是appclassloader这个加载器。
扩展类加载器extentionclassloader,加载的是javax开头的包:
在这里插入图片描述
在这里插入图片描述
怎么理解呢?rt.jar中装载的是基础功能,ext文件夹下的jar包是扩展功能(如上图)。

在这里插入图片描述
在这里插入图片描述
刚才appclassloader前面有个类前缀(上2图),这个类是jvm相关调用的入口程序。
可以根据类加载器的继承关系,打印出下图中的内容。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
根据这个实验我们可以看出类加载器是有继承关系的。
可以关注的是classloader是一个抽象类,必须被继承,如下:
在这里插入图片描述
就是通过这个抽象类来自定义类加载器。

双亲委派机制

类加载的考点:有哪几种类加载器?什么是classloader类加载器的双亲委派机制?沙箱安全机制?
双亲委派机制:我爸是李刚,有事找我爹!根据类加载器的继承结构,找一个类先从爷爷辈类加载器(bootstrapclassloader)往下找,一直找到孙子辈。也就是下图:
在这里插入图片描述
找到最下方找不到就会报错:class not found exception。
如果出现包名+类名与java自带的重合,如下图,会发生什么事呢?
在这里插入图片描述
结果是会运行失败:
在这里插入图片描述
个人理解:就因为双亲委派机制,在bootstrapclassloader类加载器这一层,就找到了String这个类,并进行了加载,但是jdk自带的String类,并没有main函数,所以出现了上图的报错。双亲委派机制就是往上捅

也就是为了用户写的代码,不污染原厂自带的代码,提供了双亲委派机制来保证沙箱安全。保证大家使用不同的类加载器加载的String都是同一个。先找到,先使用,后面的不考虑。
在这里插入图片描述
执行引擎没啥好说,加载完了就执行就ok了。
在这里插入图片描述

本地接口

在这里插入图片描述
在这里插入图片描述
我们平时所说的堆栈,指的是java栈(new出来的对象的引用放于此),而不是本地方法栈。
以线程Thread的start类引入:java的多线程是跟操作系统有关系(进程和线程是操作系统的概念)。
在这里插入图片描述
实际上底层是调用的start0这个方法。
这里补充一下线程的6种状态:
Java中的线程的状态分为6种。

  • 初始(NEW):新创建了一个线程对象,但还没有调用start()方法。
  • 运行(RUNNABLE):Java线程中将就绪(ready)和运行中(running)两种状态笼统的成为“运行”。
    线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获取cpu 的使用权,此时处于就绪状态(ready)。就绪状态的线程在获得cpu 时间片后变为运行中状态(running)。
  • 阻塞(BLOCKED):表线程阻塞于锁。
  • 等待(WAITING):进入该状态的线程需要等待其他线程做出一些特定动作(通知或中断)。
  • 超时等待(TIME_WAITING):该状态不同于WAITING,它可以在指定的时间内自行返回。
  • 终止(TERMINATED):表示该线程已经执行完毕。
    知识链接:http://www.zhiliaotang.net/jishujiaoliu/java/249.html
    如果一个线程启动2次,则会报错。如下:
    在这里插入图片描述
    因为源码里面线程的状态不对,在启动的时候就会抛出异常:
    在这里插入图片描述
    关注一下start0方法:native修饰,只有方法声明,没有方法的实现。
    在这里插入图片描述
    用native修饰的方法,调用的事操作系统的函数或者c语言函数库的功能,不是java本身的功能。
    如果是native方法就放在native栈(native方法专用)里面,因为他不是java具体实现的方法,不应该放在方法栈。
    在这里插入图片描述
    native方法的具体实现交给了底层的第三方函数库。这是早期java调用c留的一种接口。
    总结:
    在这里插入图片描述

pc寄存器

在这里插入图片描述
register:寄存器,CPU里的一小块空间。
pc寄存器就是一个指针,指着这个方法运行完了之后,下一个方法是谁。
在这里插入图片描述
pc寄存器:线程私有,内存占用很少,几乎不存在垃圾回收。

小总结

在这里插入图片描述
为什么要有双亲委派机制:因为要沙箱安全,保证调用的基础的类都是同一个。保护原生类,防止被污染。

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

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值