class 文件
硬盘上的文件
class content
内存中
Class 对象
元数据,存在于方法区
对象
存在于堆区
方法区的实现
jdk1.8之前:永久代实现,存放于堆上,会触发oom,GC
jdk1.8之后:元空间实现,存储于本地内存上
Java 虚拟机内存模型
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/e9bed3a9e9f6fe45697a7c54d1446aa3.png)
- 线程私有区域
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/0435242fda06bd0df235f25065b0644b.png)
- 线程共有区域
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/b6840d445e45926c7abb773c7b0edbd9.png)
对象初始化
创建对象过程中,先经历半初始化,先赋值为默认值
对象初始化流程:
1:分配内存空间
2:初始化对象
3:完成对象与内存地址的绑定
4:对对象进行调用
DCL
- 多线程下对象的创建会发生指令重排,B线程读取的对象可能未创建完成,导致错误
解决:
1:使用volatile禁止代码中的指令重排,volatile具有可见行,有序性,可保证指令的正常执行
2:构造线程初始化对象时,禁止其他线程对此对象的访问,在类的初始化阶段,在JVM中,
构造线程会去获取一个锁,这个锁可以同步多个线程对一个类的初始化
Java对象内存布局
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/12e3c5e994881f2047892bec4ed7b5a7.png)
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/758f3afd6a75e0091e4324f2187b7ee2.png)
对象如何定位(如何使用)
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/e23a27c8b492afe820c9b90137ef0bfa.png)
JVM 参数集合
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath:/usr/local/base
JVM线程模型
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/ce13467c95e995d9e2d263838c2a39b7.png)
主内存&工作内存同步图解
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/4be237bf8ce7ee0df53eaac2b5d5cee0.png)
| name | 作用范围 | 说明 |
---|
lock | 加锁 | 作用于主内存 | 将一个变量标识为一条线程独占状态 |
read | 读取 | 作用于主内存 | 将一个变量从主内存传输到线程的工作内存中去 |
load | 载入 | 作用于工作内存 | 将read操作主内存获取的值放入到工作内存的变量副本中 |
use | 使用 | 作用于工作内存 | 把工作内存中的变量传递给执行引擎 |
assign | 赋值 | 作用于工作内存 | 将执行引擎接收到的值赋值给本地变量 |
store | 存储 | 作用于工作内存 | 把工作内存的值传到主内存中 |
write | 写入 | 作用于主内存 | 将store从工作内存中获取的值传送到主内存的变量中 |
unlock | 解锁 | 作用于主内存 | 把一个处于线程锁定的变量释放出来,保证其他线程可对释放后的变量进行锁定 |
线程的安全性
提供了互斥访问,同一时刻只能有一个线程对它来进行操纵
一个线程对主内存的修改可以及时的被其他线程看到
一个线程观察其他线程的指令执行顺序,由于指令重排序的存在,该观察结果一般杂乱无序