JDK、JRE和 JVM的包含关系
JDK = JRE + 开发工具集(例如:java,javac编译工具等)
JRE = JVM + JavaSE标准类库(java核心类库)
如果只想运行开发好的.class文件,只需要JRE ***
1.初识JVM
-
JVM是JavaVirtualMachine(Java虚拟机),为什么要在程序和操作系统中间添加一个JVM? Java是一门抽象程度特别高的语言,提供了自动内存管理等一系列的特性。这些特性直接在操作系统上实现是不太可能的,所以就需要JVM进行一番转换。
2. JVM体系结构
3. 双亲委派机制
(详解:双亲委派机制_小段学长的博客-CSDN博客_双亲委派机制)
-
当一个类加载器收到了类加载的请求的时候,他不会直接去加载指定的类,而是把这个请求委托给自己的父加载器去加载。只有父加载器无法加载这个类的时候,才会由当前这个加载器来负责类的加载。Java中提供如下四种类型的加载器:(从顶级到下级)
Bootstrap ClassLoader(启动类加载器)
Extention ClassLoader(扩展类加载器)
Application ClassLoader(应用程序类加载器)
User ClassLoader(用户自定义类加载器)
-
这四种类加载器存在如下关系,当进行类加载的时候,虽然用户自定义类不会由bootstrap classloader或是extension classloader加载(由类加载器的加载范围决定),但是代码实现还是会一直委托到bootstrap classloader, 上层无法加载,再由下层是否可以加载,如果都无法加载,就会触发findclass,抛出classNotFoundException.
4.native:
-
凡是带了native 关键字的,说明Java的作用范围达不到了,会去调用底层c语言的库
-
会进入本地方法栈
-
调用本地方法本地接口 JNI --- java native interface
-
JNI作用:扩展Java的使用,融合不同的编程语言为java所用,最初C,c++
-
java诞生的时候,主流语言是C/C++,想要立足,必须有调用它们的程序
-
在内存中专门开辟了一块标记区域:本地方法栈(native Method Stack),登记native方法
-
在最终执行的时候,加载本地方法库中的方法(通过JNI)
5.方法区:
-
存放:静态变量,常量,类信息(构造方法,接口定义),运行时的常量池存在于方法区中,但是 实例变量存放在堆内存中,和方法区无关-----static、final、Class、常量池
6.栈
-
栈:先进后出,后进先出
-
队列:先进先出(FIFO,first input first output)
-
存放:8大基本类型+ 对象引用 +实例的方法
-
个人总结:创建一个对象的过程(还需要再百度深入下)
-
在jvm中,Class文件会在栈中创建一个类的引用对象,在方法区中创建一个实例,让这个引用指向实例
-
7.堆:
-
堆内存中还会细分三个区域:
-
新生区(伊甸园区)
-
养老区
-
永久区
-
-
我们说的垃圾回收机制(GC垃圾回收)就是针对于堆的机制,发生在伊甸园和养老区
自己理解:99%的程序的诞生、成长、毁灭都在伊甸园中,经过一次GC没有被垃圾回收的,会先进入幸存区,经过若干次轻GC,当幸存者区满了之后,会有一次重GC,将程序放入养老区,再交替轻重GC操作,直到养老区也满了,就会发生OOM异常。
-
jdk1.8之后永久存储区改名为元空间
-
图示:方法区逻辑上也属于堆,方法区右下角的方框代表常量池
逻辑上存在:物理上可能不存在
-
面试问:OOM(OutOfMemoryError)
-
尝试扩大堆内存看结果
-
分析内存,看一下哪个地方出了问题(专业工具)
-
8.GC
-
GC分为两种:轻GC(普通的GC),重GC(全局GC)
GC面试题目:
-
JVM的内存模型和分区~详细到每个区方什么?
-
堆里面的分区有哪些?Eden,from,to,老年区
-
GC算法有哪些:标记清除法,标记压缩,复制算法,引用计数器法
自己理解:
-
引用计数 就是用计数器给每个程序标记使用次数,gc的时候使用越少就越先清理
-
复制算法 主要用在伊甸园、幸存区中,每次gc,都会将Eden活的对象转移到幸存区中,每次gc后,Eden区肯定是空的。此时幸存区中from区跟to区交换接收(接受前先将两个区的对象复制到from区中,新对象存入to区中),谁空谁是to。当一个对象经历了15次GC,都还没有死,那么就会进入老年区
-
好处:没有内存的碎片
-
坏处:浪费了内存空间~因为to区永远是空的
-
最佳使用场景:对象存活度较低的时候
-
-
标记清除法:扫描标记对象,对没有标记的对象进行清除,会产生内存碎片
-
标记压缩:防止内存碎片产生。再次扫描,向一段移动存活的对象,多了移动成本。
-
-
轻GC和重GC分别在什么时候发生
总结:
-
GC:分代收集算法
-
JMM(java Memory Model)
java内存模型,面试会问到,是比较抽象的概念
作用:缓存一致性协议,用于定义多线程数据读写的规则
线程之间共享变量储存在主内存,每一个线程都有私有的本地内存(从主内存拷贝出来的)
问这个问题考察点是多线程相关:volatile/synchronized,规则主要是实现了线程数据的同步