JAVA垃圾回收的工作原理是啥?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JAVA垃圾回收的工作原理是啥?相关的知识,希望对你有一定的参考价值。
Java的垃圾回收机制是Java虚拟机提供的能力,用于在空闲时间以不定时的方式动态回收无任何引用的对象占据的内存空间。需要注意的是:垃圾回收回收的是无任何引用的对象占据的内存空间而不是对象本身,很多人回答的含义是回收对象,实际上这是不正确的。
System.gc()
Runtime.getRuntime().gc()
上面的方法调用时用于显式通知JVM可以进行一次垃圾回收,但真正垃圾回收机制具体在什么时间点开始发生动作这同样是不可预料的,这和抢占式的线程在发生作用时的原理一样。
程序员只能通过上面的方法建议JVM回收垃圾,但是JVM是否回收,同样是不可预料的。
希望能帮到你,望采纳! 参考技术A
Java虚拟机采取了一种自适应的垃圾回收技术。
停止-复制:先暂停程序(它不属于后台回收模式),然后将所有存活的对象从当前的堆中复制到另一个堆中,没有复制的对象就是垃圾,而被复制到新堆中的对象会紧凑的排列。
标记-清扫:遍历所有引用,进而找出多有存活的对象。当没找到一个存活的对象,就会给对象标记,这个过程中不会清理任何对象。只有全部标记完成之后,才会清理垃圾。
在Java虚拟机运行过程中,如果所有对象稳定,垃圾回收器效率降低的话,就会切换到"标记-清扫";同意,Java虚拟机会跟踪"标记-清扫"效果,要是堆空间出现很多碎片,就会切换到”停止-复制“;
参考技术Bjava垃圾回收的原理: 垃圾回收器通常是作为一个单独的低级别的线程运行,不可预知的情况下对内存堆中已经死亡的或者长时间没有使用的对象进行清除和回收,程序员不能实时的调用垃圾回收器对某个对象或所有对象进行垃圾回收。
回收机制有分代复制垃圾回收和标记垃圾回收,增量垃圾回收。
java垃圾回收的优点:它使得Java程序员在编写程序的时候不再需要考虑内存管理。由于有个垃圾回收机制,Java中的对象不再有"作用域"的概念,只有对象的引用才有"作用域"。
垃圾回收可以有效的防止内存泄露,有效的使用可以使用的内存。
JAVA垃圾回收机制(GC)是JAVA和C++主要区别。
因为C++的话,new之后一定要delete,才能回收内存。而JAVA能够自动回收。
其实现原理,是每当跑一个JAVA程序,他会启动一个用户不知道的优先级别低的线程来时刻监控你代码中申请的内存。
如果某个变量不再被用,则回收该部分内存。
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
来源 |
扫描二维码
获取更多精彩
海兴破颈记
以上是关于JAVA垃圾回收的工作原理是啥?的主要内容,如果未能解决你的问题,请参考以下文章