提到Java的内存管理,我始终抱有一种又爱又恨的心理。作为一门面向对象的高级语言,Java的确为减轻程序员的负担做出了巨大的努力,它的垃圾回收机制帮助百万程序员从C系语言恼人的内存管理问题中解脱出来,成为自身的一大亮点;但同时,垃圾回收机制的不可强制执行的特点,又让了解过C/C++的人觉得自动垃圾回收反而是一种累赘,自己有管理内存的能力也不能施展,在一定程度上又限制了程序员的发挥。然而,Java又不可能因为这点就放弃自己的垃圾自动回收机制,所以,能改变的只有我们自己了。
“理想”的Java垃圾回收机制
Java是打着为减轻程序员负担的旗号而诞生的一种语言。在诞生之初,的确受到了百万程序员的追捧。那么,Java的垃圾回收机制究竟是什么样的?一起来看。
· Java垃圾回收机制算法
首先,Java并没有声明JVM应该使用那种算法,所有的算法只是其回收机制可能采用的一种策略。这里列举两种:
·1.引用计数法
·2.标记法
Java在早期的时候采用的一种策略是引用计数法,即目标对象在创建时默认有一个计数器,用来统计该对象身上的引用数目,当数目为0时,表明没有变量引用该对象,则对象可回收。而垃圾回收器也主要检查回收这种对象。
除此之外,还有一种标记类的算法。
如:根搜索算法,来源于图的思想,从一个节点对象出发,只要和该对象有关,就依次传递,直到将所有节点遍历完,而剩下的没有遍历到的节点,则认为是可回收的对象,予以回收。
再如,清除类算法,这类算法有一个典型的特点。将对象记录在一张表中,还是从开头按照引用开始检索,将全程没有引用到的对象从表中释放,在将空间进行压缩;或将引用到的对象复制到新表,再将原表全部释放等。这些都是JVM可能采用的方式,具体还看虚拟机对内存对象更深度的管理方式。
·Java的垃圾回收器GC
Java中的垃圾回收器GC总共有三种类型:新生代垃圾回收器,老年代垃圾回收器和通用垃圾回收器。
·1.新生代:Serial、PraNew、Parallel Scavenge
·2.老年代:Serial Old、Parallel Old、CMS
·3.通用:G1
这三种回收器有各自的用途,具体用哪个看什么类型的对象。Serial和Serial Old都是单线程;PraNew和CMS擅长多核CPU环境;Parallel系列则追求高并发回收,对CPU利用率较高。
现实中的Java垃圾回收机制
·GC的实质
在这里直接说GC的实质显然不太妥当,但还是要简单说一下。GC依赖于JVM,是JVM中的一条低优先级的线程——这就意味着即便你使用了诸如:System.gc( ) 或 finalize( ) 这样的操作,也只是向JVM发起一个回收垃圾的请求,至于是否回收,还看JVM的调度。
·GC的局限性
GC并没有像它所期望的那样能解决所有的垃圾回收问题。比如:
·1.io类,nio类以及JDBC连接中产生的各种对象,没有显式的调用 close( ) 方法关闭读取器、套接字等;
·2.监视器类对象,包括动作监听器在内的,如果监听对象已销亡,但监听器本身还在,则也容易发生内存泄露;
·3.循环语句中有类似 Object sth = new Object( ) 这样的语句,在循环中不断创建新的对象,不断的放弃之前一次建好的对象,又不断地进行新的引用,则很容易发生内存泄露.
原文地址:https://www.cnblogs.com/fusiji/p/11409849.html