Skip to content

Commit 4b852c7

Browse files
committed
JMM
1 parent 47635e0 commit 4b852c7

File tree

1 file changed

+30
-0
lines changed

1 file changed

+30
-0
lines changed

MD/Java基础-JVM原理.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,36 @@ STW总会发生,不管是新生代还是老年代,比如CMS在初始标记
129129

130130
那么为什么一定要STW?因为在定位堆中的对象时JVM会记录下对所有对象的引用,如果在定位对象过程中,有新的对象被分配或者刚记录下的对象突然变得无法访问,就会导致一些问题,比如部分对象无法被回收,更严重的是如果GC期间分配的一个GC Root对象引用了准备被回收的对象,那么该对象就会被错误地回收。
131131

132+
## [Java内存模型](https://mp.weixin.qq.com/s/ME_rVwhstQ7FGLPVcfpugQ)
133+
定义:JMM是一种规范,目的是解决由于多线程通过共享内存进行通信时,存在的本地内存数据不一致、编译器会对代码指令重排序、处理器会对代码乱序执行等带来的问题。目的是保证并发编程场景中的原子性、可见性和有序性
134+
135+
实现:volatile、synchronized、final、concurrent包等。其实这些就是Java内存模型封装了底层的实现后提供给程序员使用的一些关键字
136+
137+
![](https://github.com/xbox1994/2018-Java-Interview/raw/master/images/j12.jpg)
138+
139+
主内存:所有变量都保存在主内存中
140+
工作内存:每个线程的独立内存,保存了该线程使用到的变量的主内存副本拷贝,线程对变量的操作必须在工作内存中进行
141+
142+
每个线程都有自己的本地内存共享副本,如果A线程要更新主内存还要让B线程获取更新后的变量,那么需要:
143+
144+
1. 将本地内存A中更新共享变量
145+
2. 将更新的共享变量刷新到主内存中
146+
3. 线程B从主内存更新最新的共享变量
147+
148+
## [happens-before](https://www.cnblogs.com/chenssy/p/6393321.html)
149+
我们无法就所有场景来规定某个线程修改的变量何时对其他线程可见,但是我们可以指定某些规则,这规则就是happens-before。特别关注在多线程之间的内存可见性。
150+
151+
它是判断数据是否存在竞争、线程是否安全的主要依据,依靠这个原则,我们解决在并发环境下两操作之间是否可能存在冲突的所有问题。
152+
153+
1. 程序次序规则:一个线程内,按照代码顺序,书写在前面的操作先行发生于书写在后面的操作;
154+
2. 锁定规则:一个unLock操作先行发生于后面对同一个锁额lock操作;
155+
3. volatile变量规则:对一个变量的写操作先行发生于后面对这个变量的读操作;
156+
4. 传递规则:如果操作A先行发生于操作B,而操作B又先行发生于操作C,则可以得出操作A先行发生于操作C;
157+
5. 线程启动规则:Thread对象的start()方法先行发生于此线程的每个一个动作;
158+
6. 线程中断规则:对线程interrupt()方法的调用先行发生于被中断线程的代码检测到中断事件的发生;
159+
7. 线程终结规则:线程中所有的操作都先行发生于线程的终止检测,我们可以通过Thread.join()方法结束、Thread.isAlive()的返回值手段检测到线程已经终止执行;
160+
8. 对象终结规则:一个对象的初始化完成先行发生于他的finalize()方法的开始;
161+
132162
## JVM调优
133163
前提:在进行GC优化之前,需要确认项目的架构和代码等已经没有优化空间
134164

0 commit comments

Comments
 (0)