目录
2.5JVM 出现 fullGC 很频繁,怎么去线上排查问题
2.6类加载为什么要使用双亲委派模式,有没有什么场景是打破了这个模式?
2.9JVM 中一次完整的 GC 流程(从 ygc 到 fgc)是怎样的
2.12stackoverflow错误,permgen space错误
2019.09.26 面试题总结,基础决定走多远。Persist!
一、JVM学习
1,JVM内存模型?
- 堆:存放对象实例,几乎所有的对象实例都在这里分配内存
- 虚拟机栈:Java方法执行的内存模型:每个方法被执行的时候都会同时创建一个栈帧(Stack Frame)用于存储局部变量表、操作栈、动态链接、方法出口等信息 存储局部变量
- 本地方法栈:本地方法栈则是为虚拟机使用到的Native方法服务。
- 方法区:存储已被虚拟机加载的类元数据信息(元空间) 类信息、常量、静态域
- 程序计数器:当前线程所执行的字节码的行号指示器
https://my.oschina.net/u/2935389/blog/3038822 这个大神写的炒鸡好啊!!!
2,JVM类加载机制?
- 1)Bootstrap ClassLoader:负责加载$JAVA_HOME中jre/lib/rt.jar里所有的class,由C++实现,不是ClassLoader子类
- 2)Extension ClassLoader:负责加载java平台中扩展功能的一些jar包,包括$JAVA_HOME中jre/lib/*.jar或-Djava.ext.dirs指定目录下的jar包
- 3)App ClassLoader:负责记载classpath中指定的jar包及目录中class
工作过程:
- 1、当AppClassLoader加载一个class时,它首先不会自己去尝试加载这个类,而是把类加载请求委派给父类加载器ExtClassLoader去完成。
- 2、当ExtClassLoader加载一个class时,它首先也不会自己去尝试加载这个类,而是把类加载请求委派给BootStrapClassLoader去完成。
- 3、如果BootStrapClassLoader加载失败(例如在$JAVA_HOME/jre/lib里未查找到该class),会使用ExtClassLoader来尝试加载;
- 4、若ExtClassLoader也加载失败,则会使用AppClassLoader来加载
- 5、如果AppClassLoader也加载失败,则会报出异常ClassNotFoundException
其实这就是所谓的双亲委派模型。简单来说:如果一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把请求委托给父加载器去完成,依次向上。
好处:
- 防止内存中出现多份同样的字节码(安全性角度)
特别说明:
- 类加载器在成功加载某个类之后,会把得到的
java.lang.Class
类的实例缓存起来。下次再请求加载该类的时候,类加载器会直接使用缓存的类的实例,而不会尝试再次加载。
类加载过程(加载-->连接(验证,准备,解析)-->初始化)
3,String s = "aaa",
类似这些题目?
- 常量池位于堆中
- 运行时常量池位于堆中
- 字符串常量池位于堆中
- 如果常量池中存在当前字符串,那么直接返回常量池中它的引用。
- 如果常量池中没有此字符串, 会将此字符串引用保存到常量池中后, 再直接返回该字符串的引用!
- 类加载后,常量池中的数据会在运行时常量池中存放!
常量池存储的是:
- 字面量(Literal):文本字符串等---->用双引号引起来的字符串字面量都会进这里面
- 符号引用(Symbolic References)
常量池(Constant Pool Table),用于存放编译期生成的各种字面量和符号引用,这部分内容将在类加载后进入方法区的运行时常量池中