經歷的幾天的分析,但願把本身學到的知識總結一下。java
系統版本:Windows Server 2008 R2 Standard
系統類型:64bit
內存:32GB
程序:在系統上部署了solr,而後寫5個線程不停的向solr查詢。
問題現象:任務管理器中物理內存一直增加,最後到了99%。可是進程佔用的內存加起來不到10G。linux
分析:windows
第一步:懷疑java程序內存溢出。
工具:jvisualvm與eclipse matapp
jvisualvm檢測是否內存溢出,若是存在內存溢出,能夠用用jmap導出dump文件,再用mat分析。mat能夠分析到每一個類佔用的內存。網上有不少mat的使用資料,你們能夠本身查詢。eclipse
我使用了jdk自帶的jvisualvm,在jdk bin目錄下jvisualvm.exe檢測內存。以下圖:工具
經過上圖,發現heap會收集的,因此不存在內存溢出。爲了熟悉,jmap,mat工具,我本身導出dump文件,用mat也分析了一下。性能
第二步:進一步分析
若是程序沒有內存溢出問題,那麼內存被什麼佔用了呢?
分析工具: RamMap與VMMap
RamMap 能夠總體分析內存使用狀況,VMMap能夠精確到某個進程ID,他們均可以查看什麼文件已經從磁盤映射到內存。spa
我用RAMMAP分析,發現大量的內存被Mapped File佔用,點擊Empty--Empty Working Sets,會釋放內存,此時任務管理器內存佔用降低到28%,可是內存一會又耗盡了(這裏有原理,網上有資料,這種方法不可取,並且很影響系統性能)。線程
內存釋放:server
經過rammap與vmmap分析,發現系統把solr索引文件加載到內存中,個人索引文件有90G。對於這個mapped file我查了好多資料。大概就這樣的:在windows server下進行大量IO操做時,爲了提升性能,系統會默認把磁盤上的文件映射到內存,可是沒有內存限制。若是磁盤文件太大,會致使內存耗盡,這也是windows server 2008 bug了。
若是限制這個內存上限呢?網上有兩種方法:SetSystemFileCacheSize ,與安裝微軟提供的Microsoft Windows Dynamic Cache Service補丁,這個網上都有,也蠻簡單,你們能夠查詢。
經過以上樑兩種方法,依然沒解決個人問題。因此,我打算在linux下試試,後續再補充博客。