JVM精彩问答(五)- CMS垃圾回收器 | WeakHashMap工作原理 | Java语法糖
01
CMS垃圾回收器的工作过程,CMS收集器和G1收集器的区别?
CMS(Concurrent Mark Sweep) 收集器:是一种以获得最短回收停顿时间为目标的收集器,标记清除算法,运作过程:「初始标记,并发标记,重新标记,并发清除」,收集结束会产生大量空间碎片。如图:
「CMS收集器和G1收集器的区别」:
- CMS收集器是老年代的收集器,可以配合新生代的Serial和ParNew收集器一起使用;
- G1收集器收集范围是老年代和新生代,不需要结合其他收集器使用;
- CMS收集器以最小的停顿时间为目标的收集器;
- G1收集器可预测垃圾回收的停顿时间;
- CMS收集器是使用“标记-清除”算法进行的垃圾回收,容易产生内存碎片;
- G1收集器使用的是“标记-整理”算法,进行了空间整合,降低了内存空间碎片。
02
WeakHashMap了解过吗?它是怎么工作的?
「WeakHashMap」 类似HashMap ,不同点在WeakHashMap的key是「弱引用」的key。
谈到「弱引用」,在这里回顾下四种引用:
- 强引用:Object obj=new Object()这种,只要强引用关系还存在,垃圾收集器就永远不会回收掉被引用的对象。
- 软引用: 一般情况不会回收,如果内存不够要溢出时才会进行回收。
- 弱引用:当垃圾收集器开始工作,无论当前内存是否足够,都会回收掉只被弱引用关联的对象。
- 虚引用:为一个对象设置虚引用的唯一目的只是为了能在这个对象被回收时收到一个系统的通知。
正是因为WeakHashMap使用的是弱引用,「它的对象可能随时被回收」。WeakHashMap 类的行为部分「取决于垃圾回收器的动作」,调用两次size()方法返回不同值,调用两次isEmpty(),一次返回true,一次返回false都是「可能的」。
WeakHashMap「工作原理」回答这两点:
- WeakHashMap具有弱引用的特点:随时被回收对象。
- 发生GC时,WeakHashMap是如何将Entry移除的呢?
第一点:WeakHashMap内部的Entry继承了WeakReference,即弱引用,所以就具有了弱引用的特点,「随时可能被回收」。看下源码:
private static class Entry<K,V> extends WeakReference<Object> implements Map.Entry<K,V> {
V value;
final int hash;
Entry<K,V> next;
/**
* Creates new entry.
*/
Entry(Object key, V value,
ReferenceQueue<Object> queue,
int hash, Entry<K,V> next) {
super(key, queue);
this.value = value;
this.hash = hash;
this.next = next;
}
......
第二点:「WeakHashMap是如何将Entry移除的?」 GC每次清理掉一个对象之后,引用对象会放到ReferenceQueue的,接着呢遍历queue进行删除。WeakHashMap的增删改查操作,就是直接/间接调用expungeStaleEntries()方法,达到及时清除过期entry的目的。可以看下expungeStaleEntries源码:
/**
* Expunges stale entries from the table.
*/
private void expungeStaleEntries() {
for (Object x; (x = queue.poll()) != null; ) {
synchronized (queue) {
@SuppressWarnings("unchecked")
Entry<K,V> e = (Entry<K,V>) x;
int i = indexFor(e.hash, table.length);
Entry<K,V> prev = table[i];
Entry<K,V> p = prev;
while (p != null) {
Entry<K,V> next = p.next;
if (p == e) {
if (prev == e)
table[i] = next;
else
prev.next = next;
// Must not null out e.next;
// stale entries may be in use by a HashIterator
e.value = null; // Help GC
size--;
break;
}
prev = p;
p = next;
}
}
}
}
03
如是否了解Java语法糖嘛?说下12种Java中常用的语法糖
语法糖(Syntactic Sugar),也称糖衣语法,让程序更加简洁,有更高的可读性。Java 中最常用的语法糖主要有泛型、变长参数、条件编译、自动拆装箱、内部类等12种。
语法糖一、switch 支持 String 与枚举;
语法糖二、 泛型;
语法糖三、 自动装箱与拆箱;
语法糖四 、 方法变长参数;
语法糖五 、 枚举;
语法糖六 、 内部类;
语法糖七 、条件编译;
语法糖八 、 断言;
语法糖九 、 数值字面量;
语法糖十 、 for-each;
语法糖十一 、 try-with-resource;
语法糖十二、Lambda表达式。
详解见:
END
来源 |
扫描二维码
获取更多精彩
海兴破颈记