最近在看关于JVM的一些知识点,之前也有了解过,可是时间一长就总会忘,索性按照自己的记忆方式去回顾一下知识点。
首先,jvm是Java程序运行的环境,全称为Java Virtual Machine
当我们写好的Java文件经过javac编译后就变成了class文件,此时就该虚拟机发挥作用了。
1:虚拟机运行时的内存组成环境:
总共包括五部分:其中三部分是线程私有的,剩余两个是线程共享的;
线程私有:
- 程序计数器:用于记录当前线程所执行的行号,即当前线程的位置。
- 虚拟机栈:用于存放要执行的方法,和局部变量。
- 本地方法区:主要是存放一下系统的本地方法。
线程共享:
- 方法区/元空间:用于存储加载的类信息,常量和静态变量等
- 堆:存放对象和数组
2:JVM有哪些部分组成,运行流程是什么?
从图中可以看出 JVM 的主要组成部分
- ClassLoader(类加载器)
- Runtime Data Area(运行时数据区,内存分区)
- Execution Engine(执行引擎)
- Native Method Library(本地库接口)
运行流程:
(1)类加载器(ClassLoader)把Java代码转换为字节码
(2)运行时数据区(Runtime Data Area)把字节码加载到内存中,而字节码文件只是JVM的一套指令集规范,并不能直接交给底层系统去执行,而是有执行引擎运行
(3)执行引擎(Execution Engine)将字节码翻译为底层系统指令,再交由CPU执行去执行,此时需要调用其他语言的本地库接口(Native Method Library)来实现整个程序的功能。
3: 堆栈的区别是什么?
1、栈内存一般会用来存储局部变量和方法调用,但堆内存是用来存储Java对象和数组的的。堆会GC垃圾回收,而栈不会。
2、栈内存是线程私有的,而堆内存是线程共有的。
3,、两者异常错误不同,但如果栈内存或者堆内存不足都会抛出异常。
栈空间不足:java.lang.StackOverFlowError。
堆空间不足:java.lang.OutOfMemoryError。
4:类加载器
JVM只会运行二进制文件,而类加载器(ClassLoader)的主要作用就是将字节码文件加载到JVM中,从而让Java程序能够启动起来。现有的类加载器基本上都是java.lang.ClassLoader的子类,该类的只要职责就是用于将指定的类找到或生成对应的字节码文件,同时类加载器还会负责加载程序所需要的资源
类加载器种类
类加载器根据各自加载范围的不同,划分为四种类加载器:
-
启动类加载器(BootStrap ClassLoader):
该类并不继承ClassLoader类,其是由C++编写实现。用于加载JAVA_HOME/jre/lib目录下的类库。
-
扩展类加载器(ExtClassLoader):
该类是ClassLoader的子类,主要加载JAVA_HOME/jre/lib/ext目录中的类库。
-
应用类加载器(AppClassLoader):
该类是ClassLoader的子类,主要用于加载classPath下的类,也就是加载开发者自己编写的Java类。
-
自定义类加载器:
开发者自定义类继承ClassLoader,实现自定义类加载规则。
由此可引出双亲委派模型:
5: 什么是双亲委派模型:
如果一个类加载器在接到加载类的请求时,它首先不会自己尝试去加载这个类,而是把这个请求任务委托给父类加载器去完成,依次递归,如果父类加载器可以完成类加载任务,就返回成功;只有父类加载器无法完成此加载任务时,才由下一级去加载。
采用双亲委派有两个好处:
(1)通过双亲委派机制可以避免某一个类被重复加载,当父类已经加载后则无需重复加载,保证唯一性。
(2)为了安全,保证类库API不会被修改
下面介绍关于垃圾回收的知识: