1. 程式人生 > >餘鎮源 搜尋引擎學習筆記|solr|solrCloud|lucene|zoie|hadoop

餘鎮源 搜尋引擎學習筆記|solr|solrCloud|lucene|zoie|hadoop

JVM 優化配置 《一》
OOM 這個縮寫就是Java程式開發過程中讓人最頭痛的問題:Out of Memory。在很多開發人員的開發過程中,或多或少的都會遇到這類問題,這類問題定位比較困難,往往需要根據經驗來判斷可能出現問題的程式碼。原因主要是 兩個:物件沒有被釋放(多種情況引起,往往是比較隱蔽的引用導致被Hold而無法被回收)。另一種就是真的Memory不夠用了,需要增加JVM的 Heap來滿足應用程式的需求。最近有同事發的關於解決OOM的問題,讓我瞭解了原來OOM除了在JVM Heap不夠時會發生,在Native Heap不夠的時候也會發生,同時JVM Heap和Native Heap存在著相互影響和平衡的關係,因此就仔細的去看了關於OOM和JVM配置優化的內容。 OOM
在 其他語言類似於C,Delphi等等由於記憶體都是由自己分配和管理,因此記憶體洩露的問題比較常見,同時也是很頭痛的一件事情。而Java的物件生命週期管 理都是JVM來做的,簡化了開發人員的非業務邏輯的處理,但是這種自動管理回收機制也是基於一些規則的,而違背了這些規則的時候,就會造成所謂的 “Memory Leak”。 OOM(Java Heap) 錯誤提示:java.lang.OutOfMemoryError。 這 類OOM是由於JVM分配的給應用的Heap Memory已經被耗盡,可能是因為應用在高負荷的情況下的卻需要很大的記憶體,因此可以通過修改JVM引數來增加Java Heap Memory(不過也不能無限制增加,後面那種OOM有可能就是因為這個原因而產生)。另一種情況是因為應用程式使用物件或者資源沒有釋放,導致記憶體消耗 持續增加,最後出現OOM,這類問題引起的原因往往是應用已不需要的物件還被其他有效物件所引用,那麼就無法釋放,可能是業務程式碼邏輯造成的(異常處理不 夠例如IO等資源),也可能是對於第三方開源專案中資源釋放了解不夠導致使用以後資源沒有釋放(例如JDBC的ResultSet等)。 幾個容易出現問題的場景:        1
.應用的快取或者Collection:如果應用要快取Java物件或者是在一個Collection中儲存物件,那麼就要確定是否會有大量的物件存入,要做保護,以防止在大資料量下大量記憶體被消耗,同時要保證Cache的大小不會無限制增加。        2 .生命週期較長的物件:儘量簡短物件的生命週期,現在採用物件的建立釋放代價已經很低,同時作了很好的優化,要比建立一個物件長期反覆使用要好。如果能夠設定超時的情景下,儘量設定超時。        3 .類似於JDBC的Connection Pool,在使用Pool中的物件以後需要釋放並返回,不然就會造成Pool的不斷增大,在其他Pool中使用也是一樣。同樣ResultSet,IO這類資源的釋放都需要注意。 解決的方法就是查詢錯誤或者是增加Java Heap Memory。對於此類問題檢測工具相當多,這裡就不做介紹了。 OOM(Native Heap) 錯誤提示:requested XXXX bytes for ChunkPool::allocate. Out of swap space。        Native Heap Memory
是JVM 內部使用的Memory,這部分的Memory可以通過JDK提供的JNI的方式去訪問,這部分Memory效率很高,但是管理需要自己去做,如果沒有把 握最好不要使用,以防出現記憶體洩露問題。JVM 使用Native Heap Memory用來優化程式碼載入(JTI程式碼生成),臨時物件空間申請,以及JVM內部的一些操作。這次同事在壓力測試中遇到的問題就是這類OOM,也就是 這類Memory耗盡。同樣這類OOM產生的問題也是分成正常使用耗盡和無釋放資源耗盡兩類。無釋放資源耗盡很多時候不是程式設計師自身的原因,可能是引用的 第三方包的缺陷,例如很多人遇到的Oracle 9 JDBC驅動在低版本中有記憶體洩露的問題。要確定這類問題,就需要去觀察Native Heap Memory的增長和使用情況,在伺服器應用起來以後,執行一段時間後JVM對於Native Heap Memory的使用會達到一個穩定的階段,此時可以看看什麼操作對於Native Heap Memory操作頻繁,而且使得Native Heap Memory增長,對於Native Heap Memory的情況我還沒有找到辦法去檢測,現在能夠看到的就是為JVM啟動時候增加-verbose:jni引數來觀察對於Native Heap Memory的操作。另一種情況就是正常消耗Native Heap Memory,對於Native Heap Memory的使用主要取決於JVM程式碼生成,執行緒建立,用於優化的臨時程式碼和物件產生。當正常耗盡Native Heap Memory時,那麼就需要增加Native Heap Memory,此時就會和我們前面提到增加java Heap Memory的情況出現矛盾。 應用記憶體組合 對 於應用來說,可分配的記憶體受到OS的限制,不同的OS對程序所能訪問虛擬記憶體地址區間直接影響對於應用記憶體的分配,32位的作業系統通常最大支援4G的內 存定址,而Linux一般為3G,Windows為2G。然而這些大小的記憶體並不會全部給JVM的Java Heap使用,它主要會分成三部分:Java Heap,Native Heap,載入資源和類庫等所佔用的記憶體。那麼由此可見,Native Heap和 Java Heap大小配置是相互制約的,哪一部分分配多了都可能會影響到另外一部分的正常工作,因此如果通過命令列去配置,那麼需要確切的瞭解應用使用情況,否則 採用預設配置自動監測會更好的優化應用使用情況。 同樣要注意的就是程序的虛擬記憶體和機器的實際記憶體還是有區別的,對於機器來說實際記憶體以及硬碟提供的虛擬記憶體都是提供給機器上所有程序使用的,因此在設定JVM引數時,它的虛擬記憶體絕對不應該超過實際記憶體的大小。
《二》 這 裡首先要說明的是這裡提到的JVM是Sun的HotSpot JVM 5和以上的版本。效能優化在應用方面可以有很多手段,包括Cache,多執行緒,各種演算法等等。通常情況下是不建議在沒有任何統計和分析的情況下去手動配置 JVM的引數來調整效能,因為在JVM 5以上已經作了根據機器和OS的情況自動配置合適引數的演算法,基本能夠滿足大部分的情況,當然這種自動適配只是一種通用的方式,如果說真的要達到最優,那 麼還是需要根據實際的使用情況來手動的配置各種引數設定,提高效能。        JVM 能夠對效能產生影響的最大部分就是對於記憶體的管理。從jdk 1.5以後記憶體管理和分配有了很多的改善和提高。 記憶體分配以及管理的幾個基本概念和引數說明: Java Hotspot Mode: server 和 client兩種模式,如果不配置,JVM會根據應用伺服器硬體配置自動選擇模式,server模式啟動比較慢,但是執行期速度得到了優化,client啟動比較快,但是執行期響應沒有server模式的優化,適合於個人PC的服務開發和測試。 Garbage Collector Policy: 在Jdk 1.5的時候已經提供了三種GC,除了原來提供的序列GC(SerialGC)以外,還提供了兩種新的GC:ParallelGC和 ConcMarkSweepGC。ParallelGC採用了多執行緒並行管理和回收垃圾物件,提高了回收效率,提高了伺服器的吞吐量,適合於多處理器的服 務器。ConcMarkSweepGC採用的是併發方式來管理和回收垃圾物件,降低垃圾回收產生的響應暫停時間。這裡說一下併發和並行的區別,併發指的是 多個程序並行執行垃圾回收,那麼可以很好的利用多處理器,而並行指的是應用程式不需要暫停可以和垃圾回收執行緒併發工作。序列GC適合小型應用和單處理器系 統(無需多執行緒互動,效率比較高),後兩者適合大型系統。 使用方式就是在引數配置中增加-XX:+UseParallelGC等方式來設定。 對於這部分的配置在網上有很多的例項可以參考,不過最終採用哪一種GC還是要根據具體的情況來分析和選擇。 Heap:        OOM 的 各種經歷已經讓每一個架構師開發人員看到了瞭解Heap的重要性。OOM已經是Heap的臨界點,不得不引起注意,然而Heap對於效能的潛在影響並未被 引起重視,不過和GC配置一樣,在沒有對使用情況作仔細分析和研究的情況下,貿然的去修改Heap配置,可能適得其反,這裡就來看一下Heap的一些概念 和對於效能的影響。 我們的應用所能夠得到的最大的Heap受三部分因素的制約:資料處理 模型(32位或者64位作業系統),系統地虛擬記憶體總數和系統的實體記憶體總數。首先Heap的大小不能超過不同作業系統的程序定址範圍,當前大部分系統最 高限度是4G,Windows通常是2G,Linux通常是3G。系統的虛擬記憶體也是分配的依據,首先是不能超過,然後由於作業系統支援硬碟來做部分的虛 擬記憶體,如果設定過大,那麼對於應用響應來說勢必有影響。再則就是要考慮同一臺伺服器上執行多個Java虛擬機器所消耗的資源總合也不能超過可用資源。就和 前面OOM分析中的一樣,其實由於OS的資料處理模型的限制,機器本身的硬體記憶體資源和虛擬記憶體資源並不一定會匹配,那麼在有限的資源下如何調整好資源分 配,對於應用來說尤為重要。 關於Heap的幾個引數設定: 說了Heap的有限資源問題以後,就來看看如何通過配置去改變JVM對於Heap的分配。下面所說的主要是對於Java Heap的分配,那麼在申請了Java Heap以後,剩下的可用資源就會被使用到Native Heap。        Xms: java heap 初始化時的大小。預設情況是機器實體記憶體的1/64。這個主要是根據應用啟動時消耗的資源決定,分配少了申請起來會降低啟動速度,分配多了也浪費。        Xmx:java heap 的 最大值,預設是機器實體記憶體的1/4,最大也就到1G。這個值決定了最多可用的Java Heap Memory,分配過少就會在應用需要大量記憶體作快取或者零時物件時出現OOM的問題,如果分配過大,那麼就會產生上文提到的第二類OOM。所以如何配置 還是根據執行過程中的分析和計算來確定,如果不能確定還是採用預設的配置。        Xmn:java heap 新 生代的空間大小。在GC模型中,根據物件的生命週期的長短,產生了記憶體分代的設計:青年代(內部也分成三部分,類似於整體劃分的作用,可以通過配置來設定 比例),老年代,持久代。每一代的管理和回收策略都不相同,最為活躍的就是青年代,同時這部分的記憶體分配和管理效率也是最高。通常情況下,對於記憶體的申請 優先在新生代中申請,當記憶體不夠時會整理新生代,當整理以後還是不能滿足申請的記憶體,就會向老年代移動一些生命週期較長的物件。這種整理和移動會消耗資 源,同時降低系統執行響應能力,因此如果青年代設定的過小,就會頻繁的整理和移動,對效能造成影響。那是否把年青代設定的越大越好,其實不然,年青代採用 的是複製蒐集演算法,這種演算法必須停止所有應用程式執行緒,伺服器執行緒切換時間就會成為應用響應的瓶頸(當然永遠不用收集那麼就不存在這個問題)。老年代採用 的是序列標記收集的方式,併發收集可以減少對於應用的影響。        Xss: 執行緒堆疊最大值。允許更多的虛擬記憶體空間地址被Java Heap使用。 以下是sun公司的效能優化白皮書中提到的幾個例子: 1.對於吞吐量的調優。機器配置:4G的記憶體,32個執行緒併發能力。 java -Xmx3800m -Xms3800m -Xmn2g -Xss128k -XX:+UseParallelGC -XX:ParallelGCThreads=20 -Xmx3800m -Xms3800m 配置了最大Java Heap來充分利用系統記憶體。 -Xmn2g 建立足夠大的青年代(可以並行被回收)充分利用系統記憶體,防止將短期物件複製到老年代。     -Xss128 減少預設最大的執行緒棧大小,提供更多的處理虛擬記憶體地址空間被程序使用。     -XX:+UseParallelGC 採用並行垃圾收集器對年青代的記憶體進行收集,提高效率。     -XX:ParallelGCThreads=20 減少垃圾收集執行緒,預設是和伺服器可支援的執行緒最大併發數相同,往往不需要配置到最大值。 2 .嘗試採用對老年代並行收集 java -Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:+UseParallelGC -XX:ParallelGCThreads=20 -XX:+UseParallelOldGC -Xmx3550m -Xms3550m 記憶體分配被減小,因為ParallelOldGC會增加對於Native Heap的需求,因此需要減小Java Heap來滿足需求。 -XX:+UseParallelOldGC 採用對於老年代併發收集的策略,可以提高收集效率。 3 .提高吞吐量,減少應用停頓時間 java -Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:ParallelGCThreads=20 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:SurvivorRatio=8 -XX:TargetSurvivorRatio=90 -XX:MaxTenuringThreshold=31 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC 選擇了併發標記交換收集器,它可以併發執行收集操作,降低應用停止時間,同時它也是並行處理模式,可以有效地利用多處理器的系統的多程序處理。 -XX:SurvivorRatio=8 -XX:MaxTenuringThreshold=31 表示在青年代中Eden和Survivor比例,設定增加了Survivor的大小,越大的survivor空間可以允許短期物件儘量在年青代消亡。 -XX:TargetSurvivorRatio=90 允許90%的空間被佔用,超過預設的50%,提高對於survivor的使用率。 類似的例子網上很多,這兒就不在列下來了,最終是否採取自己配置來替換預設配置還是要根據虛擬機器的使用情況來分析和配置。

轉自:http://blog.csdn.net/cenwenchu79/archive/2008/01/22/2059553.aspx

相關推薦

搜尋引擎學習筆記|solr|solrCloud|lucene|zoie|hadoop

JVM 優化配置 《一》 OOM 這個縮寫就是Java程式開發過程中讓人最頭痛的問題:Out of Memory。在很多開發人員的開發過程中,或多或少的都會遇到這類問題,這類問題定位比較困難,往往需要根據經驗來判斷可能出現問題的程式碼。原因主要是 兩個:物件沒有被釋放(多種情況引起,往往是比較

jQuery學習筆記(1)

ase tolower nodetype apt jquer 元素 bre 技術分享 停止 在慕課網上學習jQuery源碼,做一些筆記小研究。 第1章 節點遍歷 第2章 文檔處理 第3章 元素操作 第4章 樣式操作 第5章 事件體系 第6章 數據交互 第7章

jQuery學習筆記(2)

dom src asc turn rdo dom節點 defer ++ des 我們會認識到jQuery中一個叫做domManip的函數,這個函數的作用主要是處理DOM相關的操作,讓傳入的參數更加“幹凈”。 為什麽需要用這個domManip函數呢? 我們知道節點操作瀏覽

Vue2.x學習筆記-Vue靜態方法和靜態屬性整理

temp next 技術 spa delet 結構 又是 靜態 https Vue靜態方法和靜態屬性,其實直接在瀏覽器中可以查看到的,如下 圈起來的是其靜態屬性,但是有的屬性對象中的屬性的值又是函數。未圈起來的則是函數。 其實它來自如下各個目錄下的js文件 // src

Spring學習筆記1

ror .... AD amr pen return 接口 throw final 1.Spring中最核心的兩個類 1)DefaultListableBeanFactory   XmlBeanFactory繼承自DefaultListableBeanFactory,Def

Tomcat 7學習筆記 -9 tomcat重啟後session仍然保留

配置信息 con conf stand 加載 學習筆記 In 一段 catalina 使用Tomcat 7缺省的配置,tomcat關閉後重新啟動,發現原來的session沒有被刪掉,用原來的request獲取session仍然可以取到。但是並沒有配置session持

JUnit4學習筆記

code violate 方法註釋 lur pos 註解 dfa statement ide 先上一個在Spring-test下運行的調用棧 自底向上: JUnitStarter IDEA對JUnit的支持,調用JUnitCore.run(Runner),將註解@

springboot學習筆記之進入之前發生了啥

依賴包 cio margin padding 項目打包 定義類 定義 tro 托管 人稱: 露哥 QQ: 408365330 N01.編程就是驗證學習的最好方式 N02.為了

JDK學習筆記——Object

源碼解析 同步方法 time_wait 基礎 value 篩選 17. vat pro 一、源碼解析 public class Object { /** * 一個本地方法,具體是用C(C++)在DLL中實現的,然後通過JNI調用 */

搜尋引擎學習筆記-第二章 Web搜尋引擎工作原理和體系結構

搜素引擎,應用軟體系統,網路應用軟體系統。三個功能模組,或說三個子系統:即網頁蒐集、預處理和查詢服務。相互獨立它們的工作形成了搜尋引擎工作的三個階段,通常分別由人工啟動。第二章 Web搜尋引擎工作原理和體系結構基本要求能夠接受使用者通過瀏覽器提交的查詢詞或者短語,記作q。在一個可以接受的時間內返回一個和使用

Hadoop學習筆記之NameNode啟動流程分析二:http server啟動碼剖析

選擇 stop down gen java類 屬性 功能 集群 aslist NameNodeHttpServer啟動源碼剖析,這一部分主要按以下步驟進行:   一、源碼調用分析   二、偽代碼調用流程梳理   三、http server服務流程圖解 第一步,源碼調用分析

高階交換(防環,通訊,冗,安全)學習筆記

RSTP 基礎概述 定義 快速生成樹 RSTP 802.1W STP 802.1D MSTP 802.1S 背景 STP的速度過慢,L2,L3速度不協調 RSTP 埠狀態 1 STP埠狀態 BLOCKING  20s 阻塞資料,接受BPDU,不轉發其他資料 LISTENIN

JAVA虛擬機學習筆記之一

targe 的人 apt blank target 幽默 垃圾 服務 htm 分享一下我老師大神的人工智能教程吧。零基礎!通俗易懂!風趣幽默!還帶黃段子!希望你也加入到我們人工智能的隊伍中來!http://www.captainbed.net JAVA虛擬機源碼學習筆

redux學習筆記 - applyMiddleware

state 動作 area ogg this 圖片 let .com while 在創建store時,createStore(reducer, preloadedState, enhancer),除了reducer函數,初始狀態,還可以傳入enhancer。這個enhanc

OpenCV2學習筆記(十五):利用Cmake高速查找OpenCV函數代碼

one 生成 img log 分享 lan 學習筆記 全部 modules 在使用OpenCV時,在對一個函數的調用不是非常了解的情況下,通常希望查到該函數的官方聲明。而假設想進一步研究OpenCV的函數,則必須深入到源碼。在VS中我們能夠選中想要查

vue.js 代碼學習筆記 ----- core lifecycle

object temp art rac any ner rec char dex /* @flow */ import config from ‘../config‘ import Watcher from ‘../observer/watcher‘ import {

QuartZ .Net 學習筆記一: 碼下載與查看

net href cnblogs 方法 category solution ges 博客 存在 最近因為工作需要研究一下QuartZ .net , 之前也用過不過但沒有深入了解, 現想深入研究一下 網上相關QuartZ .net 的文章不少, 但大部分都是源於張善友的博

vue.js 代碼學習筆記 ----- helpers.js

red stat delet prop pre != help cap nbu /* @flow */ import { parseFilters } from ‘./parser/filter-parser‘ export function baseWarn (ms

java web 學習筆記 - tomcat數據

取數 nbsp pre connect 獲取 text ner auth 每次 1. 數據庫源  以前的JDBC連接步驟為:   1.加載數據庫驅動 2.通過DriverManger獲取數據庫連接connection 3.通過connection

《Android碼設計模式》學習筆記之ImageLoader

format trac dir nload download 活性 thread 大內存 idg 微信公眾號:CodingAndroid cnblog:http://www.cnblogs.com/angel88/ CSDN:http://blog.csdn.net