JVM 位置
JVM 运行时数据区 - Runtime Data Area
在jdk8,如何让方法区溢出?
模拟 OOM Jave heap space
什么是逃逸分析?
ClassLoader
反射有几种方式?
ClassLoader父类是谁?Object类
请帮我显示出来有哪些ClassLoader?
什么是双亲委派机制
某个特定的类加载器在接到加载类的请求时,首先将加载任务委托给父类加载器,依次递归,如果父类加载器可以完成类加载任务,就成功返回;只有父类加载器无法完成此加载任务时,才自己去加载。
为什么需要这个机制?防止内存中出现多份同样的字节码。
为什么需要破坏双亲委派?
因为在某些情况下父类加载器需要委托子类加载器去加载class文件。受到加载范围的限制,父类加载器无法加载到需要的文件。
以Driver接口为例,由于Driver接口定义在 JDK 当中的,而其实现由各个数据库的服务商来提供,比如 MySQL 的就写了 MySQL Connector,那么问题就来了,DriverManager(也由JDK提供)要加载各个实现了 Driver 接口的实现类,然后进行管理,但是DriverManager由启动类加载器加载,只能加载JAVA_HOME的lib下文件,而其实现是由服务商提供的,由系统类加载器加载,这个时候就需要启动类加载器来委托子类来加载Driver实现,从而破坏了双亲委派。
Execution Engine
负责解释命令,提交操作系统执行。
Native Interface:融合不同的编程语言为 Java 所用。
Native Method Stack:具体做法是Native Method Stack中登记Native方法,在Execution Engine执行时加载本地方法库。
Heap
主要分为三部分:
- Young Generation Space(Young/New)
- Tenure Generation Space(Old/Tenure)
- Permanent Space(Perm) / Metaspace
对象
对象创建
对象的创建方式:
- 使用new关键字创建对象;
- 使用Class类的newInstance方法(反射机制);
- 使用Constructor类的newInstance方法(反射机制);
- 使用Clone方法创建对象(涉及浅克隆/深克隆机制,Interface Cloneable);
- 使用(反)序列化机制创建对象(涉及Interface Serializable);
对象结构
多线程创建单例
单例特点:
- 在任何情况下,单例类永远只有一个实例存在;
- 单例需要有能力为整个系统提供这一唯一实例;
常见创建单例方式:
- 饿汉式单例;
- 懒汉式单例;
- synchronized方法+懒汉式单例 或者 synchronized代码块+懒汉式单例;
- Double Check Locking;
- 静态内置类;静态内部类虽然保证了单例在多线程并发下的线程安全性,但是在遇到序列化对象时,默认的方式运行得到的结果就是多例的。
- static代码块;
- 枚举数据类型;
TLAB
对象的访问定位
Java对象在访问的时候,我们需要通过java虚拟机栈的reference类型的数据去操作具体的对象。
由于reference类型在java虚拟机规范中只规定了一个对象的引用,并没有定义这个这个引用应该通过那种方式去定位、访问java堆中的具体对象实例,所以一般的访问方式也是取决与java虚拟机的类型。
目前主流的访问方式有通过句柄和直接指针两种方式。
句柄
直接指针
单例与序列化的那些事儿
注意看下面的评论
https://www.hollischuang.com/archives/1144
Reference
- [关于Java类加载双亲委派机制的思考] https://www.cnblogs.com/lanxuezaipiao/p/4138511.html
- [【JVM】浅谈双亲委派和破坏双亲委派] https://www.cnblogs.com/joemsu/p/9310226.html
- [高并发下线程安全的单例模式(最全最经典)] https://blog.csdn.net/cselmu9/article/details/51366946
- [Java多线程-线程安全的单例模式的实现] https://juejin.im/post/5d07a0c35188255a70479beb
- [Java对象的访问定位] https://cloud.tencent.com/developer/article/1350213