目录:
- 第一题 JVM有哪些垃圾回收器?
- 第二题 垃圾回收分为哪些阶段?
- 第三题 线程的⽣命周期?线程有⼏种状态?
- 第四题.ThreadLocal的底层原理
- 第五题.并发、并⾏、串⾏之间的区别
第一题 JVM有哪些垃圾回收器?
● 新⽣代收集器:
○ Serial
○ ParNew
○ Parallel Scavenge
● ⽼年代收集器:
○ CMS
○ Serial Old
○ Parallel Old
● 整堆收集器:
○ G1
第二题 垃圾回收分为哪些阶段?
GC分为四个阶段:
● 第⼀:初始标记 标记出GCRoot直接引⽤的对象。STW
● 第⼆:标记Region,通过RSet标记出上⼀个阶段标记的Region引⽤到的Old区Region。
● 第三:并发标记阶段:跟CMS的步骤是差不多的。只是遍历的范围不再是整个Old区,⽽只需要遍历第⼆步标记出来的Region。
● 第四:重新标记: 跟CMS中的重新标记过程是差不多的。
● 第五:垃圾清理:与CMS不同的是,G1可以采⽤拷⻉算法,直接将整个Region中的对象拷⻉到另⼀个Region。⽽这个阶段,G1只选择垃圾较多的Region来清理,并不是完全清理。
第三题 线程的⽣命周期?线程有⼏种状态?
线程通常有五种状态,创建,就绪,运⾏、阻塞和死亡状态:
- 新建状态(New):新创建了⼀个线程对象。
- 就绪状态(Runnable):线程对象创建后,其他线程调⽤了该对象的start⽅法。该状态的线程位于可运⾏线程池中,变得可运⾏,等待获取CPU的使⽤权。
- 运⾏状态(Running):就绪状态的线程获取了CPU,执⾏程序代码。
- 阻塞状态(Blocked):阻塞状态是线程因为某种原因放弃CPU使⽤权,暂时停⽌运⾏。直到线程进⼊就绪状态,才有机会转到运⾏状态。
- 死亡状态(Dead):线程执⾏完了或者因异常退出了run⽅法,该线程结束⽣命周期
阻塞的情况⼜分为三种:
6. 等待阻塞:运⾏的线程执⾏wait⽅法,该线程会释放占⽤的所有资源,JVM会把该线程放⼊“等待池”中。进⼊这个状态后,是不能⾃动唤醒的,必须依靠其他线程调⽤notify或notifyAll⽅法才能被唤醒,wait是object类的⽅法
7. 同步阻塞:运⾏的线程在获取对象的同步锁时,若该同步锁被别的线程占⽤,则JVM会把该线程放⼊“锁池”中。
8. 其他阻塞:运⾏的线程执⾏sleep或join⽅法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep状态超时、join等待线程终⽌或者超时、或者I/O处理完毕时,线程重新转⼊就绪状态。sleep是Thread类的⽅法
第四题.ThreadLocal的底层原理
- ThreadLocal是Java中所提供的线程本地存储机制,可以利⽤该机制将数据缓存在某个线程内部,该线程可以在任意时刻、任意⽅法中获取缓存的数据
- ThreadLocal底层是通过ThreadLocalMap来实现的,每个Thread对象(注意不是ThreadLocal对象)中都存在⼀个ThreadLocalMap,Map的key为ThreadLocal对象,Map的value为需要缓存的值
- 如果在线程池中使⽤ThreadLocal会造成内存泄漏,因为当ThreadLocal对象使⽤完之后,应该要把设置的key,value,也就是Entry对象进⾏回收,但线程池中的线程不会回收,⽽线程对象是通过强引⽤指向ThreadLocalMap,ThreadLocalMap也是通过强引⽤指向Entry对象,线程不被回收,Entry对象也就不会被回收,从⽽出现内存泄漏,解决办法是,在使⽤了ThreadLocal对象之后,⼿动调⽤ThreadLocal的remove⽅法,⼿动清楚Entry对象
- ThreadLocal经典的应⽤场景就是连接管理(⼀个线程持有⼀个连接,该连接对象可以在不同的⽅法之间进⾏传递,线程之间不共享同⼀个连接)
第五题.并发、并⾏、串⾏之间的区别
- 串⾏在时间上不可能发⽣重叠,前⼀个任务没搞定,下⼀个任务就只能等着
- 并⾏在时间上是重叠的,两个任务在同⼀时刻互不⼲扰的同时执⾏。
- 并发允许两个任务彼此⼲扰。统⼀时间点、只有⼀个任务运⾏,交替执⾏
如果我的内容对你有帮助,请点赞,评论,收藏。创作不易,大家的支持就是我坚持下去的动力!