垃圾回收機制
1、概述:垃圾回收機制,Java中的對象不再有“作用域”的概念,只有對象的引用才有“作用域”。垃圾回收可以有效的防止內存泄露,有效的使用空閑的內存。
內存泄露
內存泄漏的定義:對象已經沒有被應用程序使用,但是垃圾回收器沒辦法移除它們,因為還在被引用着。該內存空間使用完畢之后未回收,在不涉及復雜數據結構的一般情況下,Java 的內存泄露表現為一個內存對象的生命周期超出了程序需要它的時間長度,我們有時也將其稱為“對象游離
如何防止內存泄露
1、特別注意一些像HashMap、ArrayList的集合對象,它們經常會引發內存泄漏。當它們被聲明為static時,它們的生命周期就會和應用程序一樣長。
2、特別注意事件監聽和回調函數。當一個監聽器在使用的時候被注冊,但不再使用之后卻未被反注冊。
3、如果一個類自己管理內存,那開發人員就得小心內存泄漏問題了。” 通常一些成員變量引用其他對象,初始化的時候需要置空。
finalize作用
Java技術使用finalize()方法在垃圾收集器將對象從內存中清除出去前,做必要的清理工作。這個方法是由垃圾收集器在確定這個對象沒有被引用時對這個對象調用的。它是在Object類中定義的,因此所有的類都繼承了它。子類覆蓋finalize()方法以整理系統資源或者執行其他清理工作。finalize()方法是在垃圾收集器刪除對象之前對這個對象調用的。
垃圾回收機制算法
- 引用計數法
概述:給對象中添加一個引用計數器,每當有一個地方引用它時,計數器值就加1;當引用失效時,計數器值就減1;任何時刻計數器都為0的對象就是不再被使用的,垃圾收集器將回收該對象使用的內存。
- 復制算法
S0和S1將可用內存按容量分成大小相等的兩塊,每次只使用其中一塊,當這塊內存使用完了,就將還存活的對象復制到另一塊內存上去,然后把使用過的內存空間一次清理掉。這樣使得每次都是對其中一塊內存進行回收,內存分配時不用考慮內存碎片等復雜情況,只需要移動堆頂指針,按順序分配內存即可,實現簡單,運行高效。復制算法的缺點顯而易見,可使用的內存降為原來一半。
- 標記清除算法
標記-清除(Mark-Sweep)算法顧名思義,主要就是兩個動作,一個是標記,另一個就是清除。
標記就是根據特定的算法(如:引用計數算法,可達性分析算法等)標出內存中哪些對象可以回收,哪些對象還要繼續用。
標記指示回收,那就直接收掉;標記指示對象還能用,那就原地不動留下。

- 標記-壓縮算法
標記壓縮法在標記清除基礎之上做了優化,把存活的對象壓縮到內存一端,而后進行垃圾清理。(java中老年代使用的就是標記壓縮法)
- 分代收集算法
根據內存中對象的存活周期不同,將內存划分為幾塊,java的虛擬機中一般把內存划分為新生代和年老代,當新創建對象時一般在新生代中分配內存空間,當新生代垃圾收集器 回收幾次之后仍然存活的對象會被移動到年老代內存中,當大對象在新生代中無法找到足夠的連續內存時也直接在年老代中創建。對於新生代和老年代來說,新生代回收頻率很高,但是每次回收耗時很短,而老年代回收頻率較低,但是耗時會相對較長,所以應該盡量減少老年代的GC.
垃圾收集器
Java垃圾回收器是Java虛擬機(JVM)的三個重要模塊(另外兩個是解釋器和多線程機制)之一,為應用程序提供內存的自動分配(Memory Allocation)、自動回收(Garbage Collect)功能,這兩個操作都發生在Java堆上(一段內存快)。某一個時點,一個對象如果有一個以上的引用(Rreference)指向它,那么該對象就為活着的(Live),否則死亡(Dead),視為垃圾,可被垃圾回收器回收再利用。垃圾回收操作需要消耗CPU、線程、時間等資源,所以容易理解的是垃圾回收操作不是實時的發生(對象死亡馬上釋放),當內存消耗完或者是達到某一個指標(Threshold,使用內存占總內存的比列,比如0.75)時,觸發垃圾回收操作。有一個對象死亡的例外,java.lang.Thread類型的對象即使沒有引用,只要線程還在運行,就不會被回收。
串行回收器(Serial Collector)
單線程執行回收操作,回收期間暫停所有應用線程的執行,client模式下的默認回收器,通過-XX:+UseSerialGC命令行可選項強制指定。
並行回收器(ParNew回收器)
並行回收器在串行回收器基礎上做了改進,他可以使用多個線程同時進行垃圾回收,對於計算能力強的計算機而言,可以有效的縮短垃圾回收所需的尖際時間。
ParNew回收器是一個工作在新生代的垃圾收集器,他只是簡單的將串行回收器多線程快他的回收策略和算法和串行回收器一樣。使用XX:+UseParNewGC 新生代ParNew回收器。
並行回收集器(ParallelGC)
老年代ParallelOldGC回收器也是一種多線程的回收器,和新生代的ParallelGC回收器一樣,也是一種關往吞吐量的回收器,他使用了標記壓縮算法進行實現。
-XX:+UseParallelOldGC 進行設置
-XX:+ParallelCThread也可以設置垃圾收集時的線程教量。
Tomcat配置調優測試
- Jmeter壓力測試工具
- 調優總結
初始堆值和最大堆內存內存越大,吞吐量就越高。
最好使用並行收集器,因為並行手機器速度比串行吞吐量高,速度快。
設置堆內存新生代的比例和老年代的比例最好為1:2或者1:3。
減少GC對老年代的回收。