1.JMM的工作流程:
JMM:Java内存模型(关于并发程序的内存模型-逻辑模型)
工作内存:每个线程创建时分配的空间,线程私有。要求所有变量的读写均在工作内存中进行
主内存:所有线程共享的内存区域,存放所有共享变量(类的实例变量,类的静态变量,常量)
2.JMM三大特性
只有以下三个特性同时满足,才是线程安全的代码。
(1) 原子性:基本数据类型的访问读写,都属于原子性操作
若需要更大范围的原子性,需要使用synchronized或lock来保证
int i = 0;//一个原子性操作
i += 1;//加减乘除不算一个原子性操作
int y = x + 2;//不属于原子性操作
i = 5; //属于原子性操作
(2) 可见性:任意一个线程修改了共享变量的值,其他线程能够立即得知此修改
Synchronized,volatile,final实现可见性
(3) 有序性:逻辑上写在前面的代码优先发生于写在后面的代码
3.volatile变量的特殊规则
3.1可见性
volatile boolean shutdownRequested;
//线程1
public void shutdown(){
shutdownRequested = true;
}
public void work(){
while(!shutdownRequested){
}
}
//线程1调用了shutdown方法,线程2可以立即停下来
//对于一个volatile变量的写操作一定先与它的读操作
3.2 禁止指令重排
int x = 1;
int y = 2;
-------- volatile int z = 3;--------//加了volatile,既不会提前,也不会推迟,在这行代码之前前两句代码肯定就执行完了,而且后面两行代码还没有开始
x += 2;
y += 3;
a. volatile代码既不会提前也不会滞后执行
b. volatile 之前的代码已经全部执行完毕,且结果对后续可见,volatile之后的代码都还没有开始执行
Double-Check Singleton双重加锁单例模式
深浅拷贝:对象
浅拷贝:牵一发而动全身,拷贝对象内部的引用复用,并不会产生新对象
#####深拷贝:拷贝对象内部的引用也会产生新对象
实现深拷贝:
1.递归实现Cloneable接口
2.使用序列化(推荐)
1.内存区域划分
线程私有:(随着线程的创建而创建,随着线程销毁而回收,生命周期与线程相同,不同线程间隔离)
(1)程序计数器:记录当前线程所执行的字节码行号,唯一一块不产生OOM内存溢出的区域,native方法在程序计数器中值为0
(2)虚拟机栈:Java方法的内存模型 -Xss :设置栈的大小 StackOverFlowError OOM
(3)本地方法栈:本地方法的内存模型
在HotSpot中 本地方法栈与虚拟机栈合二为一
线程共享:
堆(GC堆):所有的对象实例以及数组实例 -Xms(设置堆的最小值) -Xmx设置堆的最大值
方法区(在JDK8之前被称为永久代):静态变量和常量以及加载的类信息
运行时常量池(方法区的一部分):符号引用、字面量
判断对象是否存活 -> 对象是否原地去世?(finalize()) -去世> 如何回收已不再存活对象(GC算法)
1. 判断对象是否存活
-
引用计数法(C++智能指针、PythonGC) :给每个对象附加一个引用计数器,如果引用自加一,如果没有地方引用,减一,当计数器值为0,垃圾回收
问题:无法解决循环引用(所以java没有采用它)
-
可达性分析算法
哪些对象可以作为GC Roots?
a.类中静态变量、常量
b.栈中的局部变量
JDK1.2之后关于引用的扩充:
(1)强引用:程序中普遍存在的,类似于 Test test = newTest();只要对象被强引用指向,GC就无法回收此对象
(2)软引用:描述有用但不必须对象(缓存对象),JDK1.2 SoftRerFerence来描述软引用,当对象仅被软引用指向,内存够用时不回收,即将发生OOM,一次性回收掉仅被软引用指向的对象
(3)弱引用:仅能存活到下一次GC之前,GC开始时,无论内存是否够用,都会回收掉仅被弱引用指向的对象。
JDK1.2 WeakPerference来描述弱引用
(4)虚引用:与对象的生存周期无关,当对象被GC时,由JVM发回一个通知。JDK1.2 PhatomRerference描述虚引用
对象自我拯救方法finalize() — 属于Object类
说明final、finally、finalize的区别
如何进行垃圾回收??
答:Java采用分代回收算法,将内存划分为新生代与老年代,其中新生代采用复制算法,老年代采用标记整理算法
请解释MinorGC与FullGC(Major GC)的区别??
新生代(对象默认在新生代产生,对象存活率较低):复制算法(Eden,Survior)
老年代(对象存活率较高):标记-整理算法