天津市某文化館網站服務器遭到病毒襲擊。網站所在硬盤全盤空間占滿,導致網站癱瘓。
如下是掛了木馬的網頁代碼:
經鴻萌工程師確認,這臺網站服務器所中為最新的VBS病毒。這種病毒會感染網站文件,所有網站靜態.html被掛了無限的代碼,直到將整個分區完全占滿。工程師看到客戶存放網站文件的F盤500G已經沒有一絲剩余空間。同時該病毒復制大量病毒代碼到可執行文件中,只要計算機調用文件,即會傳染更多文件。病毒進程如下:
此次所遇到的病毒比較特殊,由于客戶發現時間較晚,病毒已經把系統盤和網站所在分區硬盤空間占滿,系統運行緩慢,沒有任何緩存空間。致使無法使用殺毒軟件或者專殺工具進行查殺。由于網站配置比較復雜,所有網頁又被掛馬感染,解決起來比較復雜。客戶不想重做系統,于是我公司為其量身定做了個性化解決方案。
首先,將網站程序、服務和病毒進程關閉,使病毒無法繼續運行。
其次,將中毒的系統和網站程序做一個全盤的鏡像,保存原始數據,以備不測。
然后工程師通過自定義批處理工具和手工雙重查殺,利用自定義代碼清除的批處理命令,將網站中數萬個靜態網頁上面掛的病毒代碼清理完畢,歷時三天三夜的查殺,終于徹底清除了病毒。
最后重新配置網站系統,將網站恢復運營。
少小伙伴在電腦應用的時候都會發現:通常自己只打開一個網頁瀏覽,但是有的時候卻感覺電腦運行不順暢,打開資源管理器一看,處理器占用率不低,甚至會出現多個網頁的線程……對于這個現象多年來也沒人給一個合理的解釋,不過最近微軟終于主動現身解開了這個謎題。
很多人遇到這種情況,都會以為自己中了病毒,實際上并非如此。最近微軟官方在一篇技術文章中,說明了其實這是現代瀏覽器采用了多線程的架構所建構。簡單而言,當你運行一個瀏覽器的時候,這個瀏覽器其實并非是單進程軟件,而是采用了多進程的架構,瀏覽器在運行的時候,會調動不同的資源,但是在任務管理器的后臺上,都會顯示為瀏覽器的圖標,這就是瀏覽器為什么運行后會有多個后臺進程的真正原因。
微軟詳細解釋了自家Edge瀏覽器的多進程架構,同樣的原理也適用于目前世界第一大瀏覽器谷歌的Chrome瀏覽器上。微軟表示,瀏覽器采用多進程架構,瀏覽器在工作時主要被分為幾個不同的行程。
首先是瀏覽,這是主要的進程,負責視窗窗口和選項管理,控制瀏覽器的地址欄、前進/ 后退按鈕等框架、且要處理網絡請求和檔案存取。
其次是計算,通過執行網站提供的程式碼,來控制一個網頁的呈現,能夠處理超文字標記語言(HTML)、級聯樣式表(CSS)、JavaScript 和圖像等內容。
然后是GPU硬件加速的計算,這部分負責與圖形硬體相關的所有任務,比如加速圖形運算、并將處理器結果輸出到顯示器上。此外還有實用功能的進程,這部分負責了影片播放、網絡服務、資料解碼、以及集合管理,微軟和谷歌的瀏覽器可借此控制、管理、協調系統資源。
此外進程中還有附加程式,這部分負責了對各個附加程式的管理,每個進程的資源使用情況、以及同主進程/計算進程的溝通。最后還有崩潰處理的進程,如果瀏覽器發生崩潰,Crashpad Handler 能夠捕獲異常、并將錯誤報告傳遞,以查找問題和修復故障。
必須要說的是,出于可靠性和安全性的考慮,即便是同一網頁上的不同元素,也可能被分配了單獨的進程。這樣,即使是不慎被惡意軟體利用了一個計算進程中的安全漏洞,也可避免其影響另一個行程。
所以綜合來講,瀏覽器雖然只是單獨的一個軟件,但要正常使用瀏覽器,那么就需要電腦分配多個進程給它,甚至有的時候在一些復雜的網頁上,電腦的計算要耗費不少的性能,所以還會導致瀏覽器的占用率比較高,比如說一些可播放視頻的網站。這也是為什么我們在后臺看到一個瀏覽器會有這么多進程的原因。
從好處上來看,多進程的瀏覽器提升了整體的安全性,防止了不同功能在同一個進程中的串訪,而且即使出現了一些故障,比如說網頁崩潰,也只會影響其中一個進程,對瀏覽器的穩定性也有很大的重要。
通過這個釋疑,以后大家打開瀏覽器如果再看到這么多的后臺進程,大家也就不用擔心了,這是瀏覽器努力為大家服務的表現,而且在大多數時候后臺進程雖多,但是處理器資源占用并不高,除非你玩什么網頁游戲或者通過網頁觀看視頻!
產服務內存高問題
(1)根據cat監控,獲取“計算中心”中的熱點方法,進行REVIEW,修正了部分可能會導致內存泄露的方法。并進行了觀察。
(2)通過VisualVM監控,定位到部分耗時較久的操作DB熱點方法,通過增加索引等方式,把查詢性能控制在毫秒級。
(3)dump“計算中心”的內存鏡像,通過MAT等工具觀察各個對象在堆空間中所占用的內存大小、類實例數量、對象引用關系。
結論:通過以上三點,未解決和定位“計算中心”內存高問題。由此可以認為,“計算中心”的內存占用問題與代碼無關。
通過java ps| aux java 查看,“計算中心”服務實際占用的內存在4.9G左右,超過了JVM堆內存設置的大小但并未出現OOM,業務正常運行。通過free -g命令,可以發現buff/cache,3個g左右。centos中內存的分配是buff/cache + free + used=物理內存大小,系統分配給臨時文件系統的大小默認是用掉一半的物理內存,這樣會造成buff/cache很大,而free很小。最終結論可能為服務內存沒有釋放使用了buff/cache。導致服務內存占用很高。
結論:和SRE溝通實際重啟服務后,內存使用率立刻降低,但是buff/cache的大小沒有變化。由此可以認為,“計算中心”的內存占用問題與系統緩存無關。
1、通過VisualVM監控生產環境computing內存使用情況得出,在服務內存占用4.8g的情況下,堆內存(新生代 + 老年代)正常GC,在增長到2g左右會GC到300~500m,Matespace僅使用了120m左右。檢查了生產JVM參數。項目啟動參數沒有配置:-XX:MaxDirectMemorySize,來指定最大的堆外內存大小。這個閾值不配置的話,默認占用-Xmx相同的內存。在堆內內存正常的情況下,懷疑是堆外內存占用了大部分內存,導致服務內存占用很高。
結論:和SRE溝通,在生產環境找了兩臺計算中心服務實例配置 -XX:MaxDirectMemorySize 參數后實際觀察后,仍未解決“計算中心”內存高問題。由此可以認為,“計算中心”的內存占用問題與堆外內存無關。
2、在發現-XX:MaxDirectMemorySize 指定堆外內存大小的參數沒有配置后。我檢查了“計算中心”服務的啟動參數并且和之前生產環境的服務進行了對比,發現了以下問題。
1)生產及測試環境JVM參數配置混亂,同一應用不同實例多套啟動參數配置。
2)服務啟動參數,未區分JDK版本。如:JDK1.7、JDK1.8參數混用。
3)生產服務根據模板部署,導致必要JVM參數未配置,部分參數配置不需要、不合理。
4)不同類型的應用,采用統一的啟動參數配置,不具有針對性。在以上問題的基礎上,基于目前生產環境各項目統一使用的"CMS垃圾回收器"進行參數調整。針對計算中心的JDK版本(1.8),出了一套JVM配置方案。并在生產服務器調整后重啟觀察。
結論:“計算中心”生產環境服務,在運行一段時間后,仍出現內存占用高問題。由此可以認為,“計算中心”的內存占用問題與不同JDK版本的參數混用問題無關。
3、經調研,逐漸被淘汰的垃圾回收器比如ParallelOldGC和CMS,只要JVM申請過的內存,即使發生了GC回收了很多內存空間,JVM也不會把這些內存歸還給操作系統。這就會導致top命令中看到的RSS(進程RAM中實際保存的總內存)只會越來越高,而且一般都會超過Xmx的值。JDK1.9以后。默認的垃圾回收器已經選擇了G1。
G1相比CMS有更清晰的優勢:
1)CMS采用"標記-清理"算法,所以它不能壓縮,最終導致內存碎片化問題。而G1采用了復制算法,它通過把對象從若干個Region(獨立區域)拷貝到新的Region(獨立區域)過程中,執行了壓縮處理,垃圾回收后會整合空間,無內存碎片。
2)在G1中,堆是由Region(獨立區域)組成的,因此碎片化問題比CMS肯定要少的多。而且,當碎片化出現的時候,它只影響特定的Region(獨立區域),而不是影響整個堆中的老年代。
3)而且CMS必須掃描整個堆來確認存活對象,所以,長時間停頓是非常常見的,無法預測停頓時間。而G1的停頓時間取決于收集的Region(獨立區域)集合數量,在指定時間內只回收部分價值最大的空間,而不是整個堆的大小,所以相比起CMS,長時間停頓要少很多,可控很多。
4)G1選回收階段不會產生“浮動垃圾”,由于只回收部分Region(獨立區域),所以STW(stop-The-World機制簡稱STW,是在執行垃圾收集算法時,Java應用程序的其他所有線程都被掛起)時間我們可控,所以不需要與用戶線程并發爭搶CPU資源。而CMS并發清理需要占據一部分的CPU,會降低吞吐量。G1由于STW,所以不會產生"浮動垃圾",CMS在并發清理階段會產生的無法回收的垃圾。
因此在以下場景下G1更適合:
1)服務端多核CPU、JVM內存占用較大的應用。
2)應用在運行過程中會產生大量內存碎片、需要經常壓縮空間。
3)想要更可控、可預期的GC停頓周期;防止高并發下應用雪崩現象。
結論:將”計算中心“使用的垃圾回收機制升級為G1,并增加G1相關的優化內存的參數,在生產服務器進行觀察一周后發現服務內存始終穩定在了3.3G左右,業務處理性能穩定,成功解決了“計算中心”服務占用內存較高的問題,提升了系統的可用性,無需通過增加物理資源來提升服務整體性能。
計算中心“生產全部服務實例部署的服務器,使用的是JDK1.8,JDK1.8支持G1垃圾回收器,故將服務啟動參數進行統一調整:
1)原參數(主要問題:使用CMS版本,JDK1.7,1.8參數混用,未指定堆外內存大小)
/opt/java/jdk1.8.0_102/bin/java -Dapp.home=${APP_HOME} -Dspring.profiles.active=prd -Dserver.port=${SERVER_PORT} -server -Xms4G -Xmx4G -Xmn2g -Xss256k -XX:PermSize=128m -XX:MaxPermSize=512m -Djava.awt.headless=true -Dfile.encoding=utf-8 -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=75 -XX:+UseCMSInitiatingOccupancyOnly -XX:AutoBoxCacheMax=20000 -XX:-OmitStackTraceInFastThrow -XX:ErrorFile=${APP_HOME}/logs/hs_err_%p.log -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=${APP_HOME}/logs/ -Xloggc:${APP_HOME}/logs/gc.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps -jar ${APP_HOME}/webapps/${JAR_NAME} ${SERVER_PORT}"
2)新參數(使用G1做為垃圾回收器)
/opt/java/jdk1.8.0_102/bin/java -Dapp.home=${APP_HOME} -Dspring.profiles.active=prd -Dserver.port=${SERVER_PORT} -server -Xms4g -Xmx4g -Xss256k -XX:NewSize=512m -XX:MaxNewSize=512m -XX:+UseG1GC -XX:InitiatingHeapOccupancyPercent=40 -XX:G1HeapRegionSize=8m -XX:+ExplicitGCInvokesConcurrent -XX:ParallelGCThreads=4 -Dsun.rmi.dgc.server.gcInterval=36000000-Dsun.rmi.dgc.client.gcInterval=36000000-XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=256m -XX:+UseCodeCacheFlushing -XX:ReservedCodeCacheSize=256m -XX:MaxDirectMemorySize=512m -XX:GCTimeRatio=19 -XX:MinHeapFreeRatio=20 -XX:MaxHeapFreeRatio=30 -XX:ErrorFile=${APP_HOME}/logs/hs_err_%p.log -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=${APP_HOME}/logs/ -Xloggc:${APP_HOME}/logs/gc.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps -jar ${APP_HOME}/webapps/${JAR_NAME} ${SERVER_PORT}"
注:不同服務器環境,不同容器,腳本配置各不相同,要在對應腳本的基礎上進行針對性升級。
實際占用內存大小(參數):-XX:MaxPermSize(非堆) + -Xmx(堆) + -Xss(棧) + -XX:MaxDirectMemorySize(堆外)
實際占用內存大小(參數):-XX:MaxMateSpaceSize(堆外) + -Xmx(堆) + -Xss(棧) + -XX:MaxDirectMemorySize(堆外)
1、什么時候觸發Minor GC
2、觸發Minor GC 的過程
3、Full GC 的過程
1、新創建的對象一般會被分配在新生代中。常用的新生代的垃圾回收器是 ParNew 垃圾回收器,它按照 8:1:1 將新生代分成 Eden 區,以及兩個 Survivor 區。創建的對象將 Eden 區全部擠滿,這個對象就是「擠滿新生代的最后一個對象」。此時,Minor GC 就觸發了。
2、在正式 Minor GC 前,JVM 會先檢查新生代中對象,是比老年代中剩余空間大還是小。Minor GC 之后 Survivor 區放不下剩余對象,這些對象就要進入到老年代,所以要提前檢查老年代是不是夠用。
3、老年代剩余空間大于新生代中的對象大小,那就直接 Minor GC,GC 完 survivor 不夠放,老年代也絕對夠放。老年代剩余空間小于新生代中的對象大小,這時候就要進入老年代空間分配擔保規則。
4、老年代空間分配擔保規則:如果老年代中剩余空間大小,大于歷次 Minor GC 之后剩余對象的大小,那就允許進行 Minor GC。因為從概率上來說,以前的放的下,這次的也應該放的下。那就有兩種情況:
緊接上一節 Full GC 之后,老年代任然放不下剩余對象,就只能 OOM。未開啟老年代分配擔保機制,且一次 Full GC 后,老年代任然放不下剩余對象,也只能 OOM。開啟老年代分配擔保機制,但是擔保不通過,一次 Full GC 后,老年代任然放不下剩余對象,也是能 OOM。注:
作者: zhfeat
出處:https://www.cnblogs.com/zhfeat/p/13261543.html
*請認真填寫需求信息,我們會在24小時內與您取得聯系。