cms演算法
『壹』 請問php中的CMS是什麼意思
CMS(Content Management System),中文叫作整站系統、文章系統,大概2004以前,如果想進行網站內容管理,基本上都是靠手工維護,但千變萬化的信息流,但沒有好的程序支持,還繼續靠手工完成是不可能的事,如果有一個好的系統來支撐你的網站,那將節省大量的人力物力,開發者就可能給客戶一個軟體包,可以用它定期人工修改網站。只要你配置安裝好,你的編輯,在線記者,更新員只要定期更新數據,剩下的事就交給CMS去處理。
=== Asp ===
動易CMS管理系統,官方網站:http://www.asp163.net/
這套是國產AspCMS中非常強大的系統,從3.0的簡單的一個文章系統到現在的2005的版本,一路走來,動易不斷完善,而且也不斷加強功能,包括個人版,學校版,政府版,企業版,後台包括的功能,信息發布,類別管理,許可權控制,信息採集,而且跟第三方的程序,比如論壇,商城(2005的已經自帶了), blog可以完美結合,基本上可以滿足一個中大型網站的要求,但Asp和Access的的局限性,還有本身功能Dll的限制,使得免費版差不多成雞肋,
風訊 官方網站:http://www.foosun.cn/
風訊的系統功能強大,自由度高,是現在人氣比較高的系統之一,可以根據自己的想法做出一個網頁從而建立一個有自我風格的網站,更新速度快,一直有新的版本出現,現在又開放採集、下載、投稿、圖片整站管理系統,第三方整合等功能,開源是它最大特點,希望保持。然後缺點就是後台人性化差了一點,上手有點難度,而且連一套默認的模板都沒有,因為自由度太高了,讓一些新手更難上手,還有就是免費版的生成靜態發布的效率不高。3.1已經出來一段時間了,願各方面都更上一層樓。
新雲網站管理系統 官方http://www.newasp.cn/
一款Asp的CMS後起之秀,發現有不少的網站都在使用。由文章、下載、商城、留言、用戶管理五大功能模塊和廣告、公告、連接、統計、採集、模板管理、資料庫管理等多個通用模塊組成,而且功能確實有一些值得稱道的地方,不過又是DLL的,免費版有不少的限制,但對一個簡單基本的網站來說,功能夠用了。
喬客(asp) 官方網站:http://www.joekoe.com/
這個系統已經很久了,但好像一直存活在動易和風訊兩者之間,現在3.0的Joekoe CMS出來了,但另我比較失望,相比免費版的1.2,功能是增強了,但也Dll,這個可能也是國產程序的一個特色罷了。它本身已經是一個融合度非常高的系統,有商城,新聞,下載,論壇,留言,影視,博客圈等,感覺有那麼點WEB2.0 的味道,,不想怎麼修改的朋友直接拿去就可以用了。
NB文章系統(asp) 官方:http://forum.nbarticle.com/default.asp
現在最新的是v2.1 RC1 ,上手挺容易,後台很簡潔,安全性能不錯,發布效率比較高,當然想到同類型的,RSS不錯,它也是將模板寫入資料庫,但修改還是蠻方便。不過這樣相對來說功能是少了一些,而且官方就一個論壇技術支持,論壇的人氣差了一點。
漸飛新聞出版系統(asp) 官方網站: http://www.xunt.net/
這個系統也有一段時日了,不過到現在還是1.1的版本,以前名頭特別響,
不過主要針對的是商業客戶,看客戶演示,個個都像門戶,但因為沒免費版的支撐,市場也一直沒做大。
大世紀(Asp) 官方網站:http://www.bigcn.net/
很老的系統,差不多就算是個文章,新聞系統,
現在連官方都打不開了,這樣的估計也沒多少前景。
tsys信息發布系統 官方:http://www.tsyschina.com
非常遺憾 2.0剛剛出測試版,作者就好像人間蒸發一樣消失了!不過對於一個免費開源,沒有版權的CMS來說我們也沒有什麼可要求的!拋開強大,但可能不成熟(我沒用過)的2.0不談!單說1.1版!從 1.1就可以說他是ASP CMS中的老大了!在TSYS的各個版本中均沒有出現過重大的安全漏洞而且對於目前1.1來說已經是很完善成熟的了!tsys和一般的Asp 的CMS不一樣!他的功能並非由本身而定!而是根據使用者的能力而定!使用者越厲害 TSYS本身也可以變的更厲害!因為TSYS可以說是一個核心!而其他的東西和功能均需要使用者自己搞定!從這點來說!TSYS的功能可以說是無限的!但這也決定了TSYS不會流行起來!說白了只有高手使用TSYS才能把TSYS的優點發揮的淋漓盡致!可惜啊....
說到php的CMS,也跟Asp差不多,可以算是百花齊放。
PhpArtile 官方:http://www.21ds.net/
這個算是國內phpCms的祖宗了,PA由 PHP 語言開發, 使用 MySQL 資料庫保存數據 ,
為中小型網站發表文章, 存放資料, 新聞發布提供一個完美的解決方案。
做了好幾年了,3.0遲遲還在開發中,今年出了2.1火了一陣,又熄滅了,以前用的人挺多的,
現在基本上沒落了
phpcms 官方:http://www.phpcms.cn/
好像以前是9466Article的官方,本來9466做得挺好的,不知為什麼突然zend加密了,
繼承了9466的優點,上手,結構,提供插件介面,可自主開發插件,自主製作語言包,
自主設計模板風格,免費版可永久使用,功能還可以。
OKphp http://cn.okphp.com
同樣加密的,免費版也不見怎麼有人用,系統倒是開發了好久了,整合了論壇,blog,新聞,
分有企業版,門戶版,還有免費的,看起來像老外的Nuke,個人感覺沒多少特別之處。
美麗心雨 官方:http://www.xydw.com/
美麗心雨CMS是心雨動網獨立開發製作的網站管理系統,基本上網站管理的功能有了,
從1.01到現在的1.4,官方的開發人員也一直在努力中。
DedeCMS 官方:http://dedecms.com/
這是一套令人愛憎分明的系統,首先它是國內一款開源的系統,2.x的時候功能都已經另它的fans為之瘋狂,
非常靈活的定製,強大的功能,簡潔的操作,但2.x的瓶頸問題:大數據處理,到3.0的時候可能會解決,
但3.0的一直跳票,遲遲不見發布,另很多人都非常失望,希望能在3.0的時候看到一個全新的Dedecms,
當然也支持開源產品。
Ss-cms 官方:http://www.ss-cms.com/
作者我見過,一個非常有活力的傢伙,程序跟他一樣,國產的開源系統,
生成靜態,信息採集,文章和下載集成,
但作者都是出於興趣愛好開發,1.0出來後就不見蹤影了,好像現在在搞書庫
隨意Cmsez CMS 官方:http://www.cmsez.com/
程序的作者和Ss-cms的作者是好朋友,他也是出於個人愛好做這個,而且主要面向企業用戶,
Cmsez集成了豐富的功能模塊,http://www.colorbird.com/(七色?...??型客戶,
看七色鳥,你或許可以知道他的作品如何了。
CMSware 官方:http://www.cmsware.com/
一個非常不錯的CMS系統,比較看好的他的後台操作簡介,一些新技術,比如Ajax的應用,Wap的功能,
還有它的PSN的發布,節點和模塊的定製,,自定義模型,資料庫欄位,
率先引進的工作流的概念,更多的發布自由度,非常強大的模板體系,
確實處處體現了自由的思想,讓您體驗自由管理的非凡感受.
Ecms 帝國網站管理系統 官方:http://www.phome.net/
可以說這個是最讓我值得寫的東西,作者wm_chief是個超人,偶像啊
官方的title裡面是 在這里只有原創,那傢伙也是瘋子,
比如資料庫管理,論壇,新聞,下載,flash,域名交易系統等,
還包括JSP的版本,都是自己一個人寫,還有一個人搞定後期服務,客戶支持,產品宣傳。
還要每天抽時間灌水AD,ECMS的功能非常多,包括下載,flash,商城,圖片,新聞,友情鏈接,廣告管理等,
比如一些遠程發布,刷新效率,類別管理,許可權細分,萬能的論壇介面,信息採集,附件管理等這些都是Ecms特別的亮點,
而且免費版也不錯,作者WC也非常虛心接受客戶的建議,
基本上任何一個小的功能,都力求做到最好,
他明白用戶的需求,一切能從用戶本身出發的系統才是好的系統,
3.6已經出來了,而且下一個版本可能會結合EXE軟體發布,刷新的功能,讓我們拭目以待。
ecms的典型客戶 www.chinahtml.com
.Net
動網新聞(asp.net)
最新的4.X也出來了,也是DLL的,不過系統是.NET的,不過我個人不趨向使用DLL的系統,
運行速度快,效率高,安全做足。
不過以前3.X的沒有Dll,感覺也蠻好的,
缺點就是風格改起來不容易。
現在加密了,反而能更快上手,不過這樣可以定製的地方就少了。
還有一個倒奶CMS,也是.net的,不見什麼特別之處,一筆帶過
JSP
大概有這些:
Netark CMS
方正翔宇CMS
開源的Magnolia
Magnolia CMS
不過JSP的應用門檻對我們個人用戶來說,有點高,也不想多提
當然還有一些系統比如說,Asp的國產FeitecCMS ,WpsCms等,國外的FullXML,php的國產有MePhp,天下站長php等,
都沒見多少特色,不用也罷。
TurboCMS 這樣只面向企業用戶,幾十萬的系統,我們也不用考慮。
Struts中文版,Spring 開源系統,Gpower CMS,還有java的 Ion,opencms,Jboss Nuke等老外做的,
國外的php的比如phpnuke,phppost,還有非常昂貴的phpcow,Bitrix Site Manager-CMS(99),
比較廉價的Subdreamer,koobi CMS,ActiveKB團隊的ArticleLive NX,newsphp
還有免費的Xoops,功能繁多的玩意,Mambo這樣的開源系統,還有Mambo的變種LimboCMS,Mamhoo 。
不符合國情的,在國內也沒見流行
還有國外CMS的大全:http://bbs.chinahtml.com/t602.html 自己有空去翻翻
如果要比較老外CMS的也可以進去看看:http://bbs.chinahtml.com/t5429.html 直接選擇2-10項,,有詳細的列表說。
現在每個CMS功能介紹上都會說自己的產品如何強大,比如說什麼模板體系如何好,
緩存技術如何高明,刷新效率,負載容量如何強,操作如何如何簡單,容易上手,跟第三方無縫結合,還有功能模塊的如何豐富,生成靜態發布,信息採集……
吹牛誰都會,大家都會寫,關鍵是客戶如何認為,反正一句話,適合自己的就是最好的。
很長時間以來,我一直在尋找一個優秀的CMS(Content Management System 內容管理系統)作為自己網站的核心系統。為此我專門研究過postnuke、Xoops等一些基於LAMP架構的CMS,還研究過基於Java的OpenCMS和基於J2EE架構的JBoss的Nukes。OpenCMS是一個非常不錯的系統,只可惜架構與自己的方向不符,而且需要大量的二次開發工作,只好放棄。這些CMS系統或多或少都有讓自己很不滿意的地方,我也並不想耗費太多的精力自己來開發一套,網站的計劃甚至一度擱置了下來,直到我看到了eZ publish。
找到eZ publish還是偶然看到www.php.net上左側的eZ Systems的鏈接,ez的網址是www.ez.no,一個挪威的公司開發的系統,試用後我得出了結論,它就是我一直在尋找的東西。
在CMS選型的過程中我經常的問自己,什麼才是好的CMS?
現在要我回答這個問題的話,我會說適合自己需要的就是好的系統。因為這期間經歷了太多的考慮或者說猶豫,有時候甚至是痛苦的。
首先是語言的選擇,是基於Java的還是PHP的呢?因為我本人以前是從事Java的開發工作,鍾情於Java優美的語言風格和架構,所以一度考慮採用OpenCMS,而且OpenCMS號稱可以承受很大強度的訪問量,這聽起來似乎很誘人。然而我在研究它的過程中發現OpenCMS復雜且龐大,文檔過時,需要花費大量的精力進行二次開發,作為業余時間搞網站的我們來說的確沒有這個精力,於是只好放棄。現在要我回頭看這個問題,我認為我的選擇是正確的,選擇CMS要考慮到自身的二次開發和日後維護的能力與精力耗費以及網站的業務需要,選擇開發維護快速方便和自己也比較熟悉的的LAMP架構已經能適應我網站的需要。
其次,在基於LAMP架構的CMS系統中進行橫向比較時,優劣比較明顯。postnuke與Xoops這類CMS應該說十分的簡單易用,基本上不需要做什麼二次開發,基礎功能就可以滿足一般的需要。
而eZ publish相比起來要專業和龐大的多,它有自己專有的核心庫和模版語言,面向對象的思想在eZ里體現的十分明顯,甚至在它的配置文件中都有體現,內容與形式的分離做得相當好,擴展方便。而且它本身自帶有article、gallery、webshop和forum等這些我所需要的功能,不需要再二次開發,十分的方便。而且在www.ez.no上有關於eZ publish的詳細開發和使用文檔可供參考。
eZ publish是eZ System公司發布的,專業的公司保證了系統以後的升級與維護的持續性,這一切都是我選擇eZ的理由。
在整個CMS選型直到確定下eZ publish後,我發現這個過程持續時間是漫長而又痛苦的。經歷了許多的波折,但也的確是值得的,畢竟CMS是整個網站的核心,很慶幸有eZ publish的存在而且我也發現了它。
一個好消息,eZ publish3.5近兩天就會推出最終版了,而我的兩個網站www.cnwebservices.com與www.o2.cn也將陸續推出。首先在12月初推出的將是關於LAMP與網站建設的技術性網站www.cnwebservices.com,是基於eZ publish CMS的網站,屆時會有更多關於LAMP與開源項目的技術文章,敬請大家留意。
隨著BLOG程序的普及,越來越多的普通用戶開始了解或者接觸到CMS(網站內容管理系統)這一概念。BLOG做為一種相對簡單的內容管理系統,實 際上向更多的普通網民普及了網站後面的基本動態技術。我相信將來會有越來越多的人會不滿足於只用BLOG來書寫和表達,會有更多的人將會應用到較為復雜的 多人參與型CMS系統,這會與網路發展的去中心化趨勢有關,一個中小型的,以一個或者幾個人創造為主,大量讀者鬆散參與的網站,會比中心化壟斷型的網站更 具有活力。同時,它也使創造者的利益得到更加合理的體現。現在一個好的,內容專一又專業的小網站,很容易會得到足夠的流量,僅僅通過GOOGLE類似的廣 告就可以維持。
這個過程中一個決定性的因素就是網站構建技術和網站本身的服務內容之間的分離。幾年前,在BLOGGER之 前,要想在網路上順利的發表,還真的需要知道一點技術,而現在,大多數天天書寫著BLOG的人,都是沒有任何技術背景的普通用戶。隨著開源CMS項目如火 如茶的發展趨勢,加上未來主機託管或者虛擬主機租用費用的不斷降低,一個不具備專業網路技術知識的人,都可以輕易的建立自己的網站,如果說這幾年BLOG 的發展解放了普通民眾的發言權,這種功能更為復雜的CMS系統的發展,將會促使那些更加會創造,會關心別的用戶的需求的人的創造得到利益上的回報。知識有 價,但會是更合理的方式。
甚至,可以預言,這可能會是一輪新的去中心化的開始,即中小型網站對大型內容門戶的蠶食的開始。內容是互聯網的生命,內容管理系統將那些深藏在用戶 內心深處的想法流暢的表達出來,從而使整個網路充滿活力。其實你稍稍想一想就可以發現,這本身並不是什麼「蠶食」,因為這些內容門戶才是內容事實上的掠奪 者,越來越多的報紙對新浪等的「海量」轉載產生不滿只是這個事實的冰山一角。
將來轉載型的網站的重要性一定會不斷降低,除非它在這個過程中創造了新的對用戶有利的價值,隨著GOOGLE演算法的改進,將來出現在搜索結果首頁的東西一定是那些用戶最想需要的東西,而且是一定是那些創造者的網頁。
所以現在很關注CMS系統的情況,正好,OPENSOURCE CMS進行了一個最佳網站內容管理系統的投票評選,不如就從這里入手去探尋CMS系統的情況。
現在排在前5名,也就是最終入圍項目的名單是:
Drupal
e107
Joomla!
Plone
Xoops
接下來就准備把這幾個東西一一試用一下。顯然這些最受歡迎的東西並不一定能夠代表最有創造性的想法,一定有更多的想法隱藏在那些不為人關注的項目中,不過,這應該是能夠代表潮流的東西。
『貳』 三色標記法與垃圾回收器(CMS、G1)
JVM中的CMS、G1垃圾回收器所使用垃圾回收演算法即為三色標記法。
三色標記法將對象的顏色分為了黑、灰、白,三種顏色。
存在問題:
浮動垃圾:並發標記的過程中,若一個已經被標記成黑色或者灰色的對象,突然變成了垃圾,此時,此對象不是白色的不會被清除,重新標記也不能從GC Root中去找到,所以成為了浮動垃圾,這種情況對系統的影響不大,留給下一次GC進行處理即可。
對象漏標問題(需要的對象被回收):並發標記的過程中,一個業務線程將一個未被掃描過的白色對象斷開引用成為垃圾(刪除引用),同時黑色對象引用了該對象(增加引用)(這兩部可以不分先後順序);因為黑色對象的含義為其屬性都已經被標記過了,重新標記也不會從黑色對象中去找,導致該對象被程序所需要,卻又要被GC回收,此問題會導致系統出現問題,而CMS與G1,兩種回收器在使用三色標記法時,都採取了一些措施來應對這些問題,CMS對增加引用環節進行處理(Increment Update),G1則對刪除引用環節進行處理(SATB)。
在JVM虛擬機中有兩種常見垃圾回收器使用了該演算法:
CMS(Concurrent Mark Sweep)
CMS,是非常有名的JVM垃圾回收器,它起到了承上啟下的作用,開啟了並發回收的篇章。
但是CMS由於許多小問題,現在基本已經被淘汰。
增量更新(Increment Update)
在應對漏標問題時,CMS使用了Increment Update方法來做:
在一個未被標記的對象(白色對象)被重新引用後,==引用它的對象==,若為黑色則要變成灰色,在下次二次標記時讓GC線程繼續標記它的屬性對象。
但是就算時這樣,其仍然是存在漏標的問題:
在一個灰色對象正在被一個GC線程回收時,當它已經被標記過的屬性指向了一個白色對象(垃圾)
而這個對象的屬性對象本身還未全部標記結束,則為灰色不變
而這個GC線程在標記完最後一個屬性後,認為已經將所有的屬性標記結束了,將這個灰色對象標記為黑色,被重新引用的白色對象,無法被標記
補充,CMS除了這個缺陷外,仍然存在兩個個較為致命的缺陷:
解決方案:使用Mark-Sweep-Compact演算法,減少垃圾碎片
當JVM認為內存不夠了,再使用CMS進行並發清理內存可能會發生OOM的問題,而不得不進行Serial Old GC,Serial Old是單線程垃圾回收,效率低
解決方案:降低觸發CMS GC的閾值,讓浮動垃圾不那麼容易占滿老年代
G1(Garbage First)
從G1垃圾回收器開始,G1的物理內存不再分代,而是由一塊一塊的Region組成;邏輯分代仍然存在。
前置知識 — Card Table(多種垃圾回收器均具備)
由於在進行YoungGC時,我們在進行對一個對象是否被引用的過程,需要掃描整個Old區,所以JVM設計了CardTable,將Old區分為一個一個Card,一個Card有多個對象;如果一個Card中的對象有引用指向Young區,則將其標記為Dirty Card,下次需要進行YoungGC時,只需要去掃描Dirty Card即可。
Card Table 在底層數據結構以 Bit Map實現。
CSet(Collection Set)
SATB(Snapshot At The Beginning)
在應對漏標問題時,CMS使用了SATB方法來做:
因為SATB在重新標記環節只需要去重新掃描那些被推到堆棧中的引用,並配合Rset來判斷當前對象是否被引用來進行回收;
並且在最後G1並不會選擇回收所有垃圾對象,而是根據Region的垃圾多少來判斷與預估回收價值(指回收的垃圾與回收的STW時間的一個預估值),將一個或者多個Region放到CSet中,最後將這些Region中的存活對象壓縮並復制到新的Region中,清空原來的Region。
問題:G1會不會進行Full GC?
會,當內存滿了的時候就會進行Full GC;且JDK10之前的Full GC,為單線程的,所以使用G1需要避免Full GC的產生。
解決方案:
加大內存;
提高CPU性能,加快GC回收速度,而對象增加速度趕不上回收速度,則Full GC可以避免;
降低進行Mixed GC觸發的閾值,讓Mixed GC提早發生(默認45%)
G1的第一篇paper(附錄1)發表於2004年,在2012年才在jdk1.7u4中可用。oracle官方計劃在jdk9中將G1變成默認的垃圾收集器,以替代CMS。為何oracle要極力推薦G1呢,G1有哪些優點?
首先,G1的設計原則就是簡單可行的性能調優
開發人員僅僅需要聲明以下參數即可:
其中-XX:+UseG1GC為開啟G1垃圾收集器,-Xmx32g 設計堆內存的最大內存為32G,-XX:MaxGCPauseMillis=200設置GC的最大暫停時間為200ms。如果我們需要調優,在內存大小一定的情況下,我們只需要修改最大暫停時間即可。
其次,G1將新生代,老年代的物理空間劃分取消了。
這樣我們再也不用單獨的空間對每個代進行設置了,不用擔心每個代內存是否足夠。
取而代之的是,G1演算法將堆劃分為若干個區域(Region),它仍然屬於分代收集器。不過,這些區域的一部分包含新生代,新生代的垃圾收集依然採用暫停所有應用線程的方式,將存活對象拷貝到老年代或者Survivor空間。老年代也分成很多區域,G1收集器通過將對象從一個區域復制到另外一個區域,完成了清理工作。這就意味著,在正常的處理過程中,G1完成了堆的壓縮(至少是部分堆的壓縮),這樣也就不會有cms內存碎片問題的存在了。
在G1中,還有一種特殊的區域,叫Humongous區域。 如果一個對象佔用的空間超過了分區容量50%以上,G1收集器就認為這是一個巨型對象。這些巨型對象,默認直接會被分配在年老代,但是如果它是一個短期存在的巨型對象,就會對垃圾收集器造成負面影響。為了解決這個問題,G1劃分了一個Humongous區,它用來專門存放巨型對象。如果一個H區裝不下一個巨型對象,那麼G1會尋找連續的H分區來存儲。為了能找到連續的H區,有時候不得不啟動Full GC。
PS:在java 8中,持久代也移動到了普通的堆內存空間中,改為元空間。
對象分配策略
說起大對象的分配,我們不得不談談對象的分配策略。它分為3個階段:
對TLAB空間中無法分配的對象,JVM會嘗試在Eden空間中進行分配。如果Eden空間無法容納該對象,就只能在老年代中進行分配空間。
最後,G1提供了兩種GC模式,Young GC和Mixed GC,兩種都是Stop The World(STW)的。下面我們將分別介紹一下這2種模式。
Young GC主要是對Eden區進行GC,它在Eden空間耗盡時會被觸發。在這種情況下,Eden空間的數據移動到Survivor空間中,如果Survivor空間不夠,Eden空間的部分數據會直接晉升到年老代空間。Survivor區的數據移動到新的Survivor區中,也有部分數據晉升到老年代空間中。最終Eden空間的數據為空,GC停止工作,應用線程繼續執行。
這時,我們需要考慮一個問題,如果僅僅GC 新生代對象,我們如何找到所有的根對象呢? 老年代的所有對象都是根么?那這樣掃描下來會耗費大量的時間。於是,G1引進了RSet的概念。它的全稱是Remembered Set,作用是跟蹤指向某個heap區內的對象引用。
在CMS中,也有RSet的概念,在老年代中有一塊區域用來記錄指向新生代的引用。這是一種point-out,在進行Young GC時,掃描根時,僅僅需要掃描這一塊區域,而不需要掃描整個老年代。
但在G1中,並沒有使用point-out,這是由於一個分區太小,分區數量太多,如果是用point-out的話,會造成大量的掃描浪費,有些根本不需要GC的分區引用也掃描了。於是G1中使用point-in來解決。point-in的意思是哪些分區引用了當前分區中的對象。這樣,僅僅將這些對象當做根來掃描就避免了無效的掃描。由於新生代有多個,那麼我們需要在新生代之間記錄引用嗎?這是不必要的,原因在於每次GC時,所有新生代都會被掃描,所以只需要記錄老年代到新生代之間的引用即可。
需要注意的是,如果引用的對象很多,賦值器需要對每個引用做處理,賦值器開銷會很大,為了解決賦值器開銷這個問題,在G1 中又引入了另外一個概念,卡表(Card Table)。一個Card Table將一個分區在邏輯上劃分為固定大小的連續區域,每個區域稱之為卡。卡通常較小,介於128到512位元組之間。Card Table通常為位元組數組,由Card的索引(即數組下標)來標識每個分區的空間地址。默認情況下,每個卡都未被引用。當一個地址空間被引用時,這個地址空間對應的數組索引的值被標記為」0″,即標記為臟被引用,此外RSet也將這個數組下標記錄下來。一般情況下,這個RSet其實是一個Hash Table,Key是別的Region的起始地址,Value是一個集合,裡面的元素是Card Table的Index。
Young GC 階段:
Mix GC不僅進行正常的新生代垃圾收集,同時也回收部分後台掃描線程標記的老年代分區。
它的GC步驟分2步:
全局並發標記(global concurrent marking)
拷貝存活對象(evacuation)
在進行Mix GC之前,會先進行global concurrent marking(全局並發標記)。 global concurrent marking的執行過程是怎樣的呢?
在G1 GC中,它主要是為Mixed GC提供標記服務的,並不是一次GC過程的一個必須環節。global concurrent marking的執行過程分為五個步驟:
初始標記(initial mark,STW)
在此階段,G1 GC 對根進行標記。該階段與常規的 (STW) 年輕代垃圾回收密切相關。
根區域掃描(root region scan)
G1 GC 在初始標記的存活區掃描對老年代的引用,並標記被引用的對象。該階段與應用程序(非 STW)同時運行,並且只有完成該階段後,才能開始下一次 STW 年輕代垃圾回收。
並發標記(Concurrent Marking)
G1 GC 在整個堆中查找可訪問的(存活的)對象。該階段與應用程序同時運行,可以被 STW 年輕代垃圾回收中斷
最終標記(Remark,STW)
該階段是 STW 回收,幫助完成標記周期。G1 GC 清空 SATB 緩沖區,跟蹤未被訪問的存活對象,並執行引用處理。
清除垃圾(Cleanup,STW)
在這個最後階段,G1 GC 執行統計和 RSet 凈化的 STW 操作。在統計期間,G1 GC 會識別完全空閑的區域和可供進行混合垃圾回收的區域。清理階段在將空白區域重置並返回到空閑列表時為部分並發。
提到並發標記,我們不得不了解並發標記的三色標記演算法。它是描述追蹤式回收器的一種有用的方法,利用它可以推演回收器的正確性。 首先,我們將對象分成三種類型的。
根對象被置為黑色,子對象被置為灰色。
繼續由灰色遍歷,將已掃描了子對象的對象置為黑色。
遍歷了所有可達的對象後,所有可達的對象都變成了黑色。不可達的對象即為白色,需要被清理。
這看起來很美好,但是如果在標記過程中,應用程序也在運行,那麼對象的指針就有可能改變。這樣的話,我們就會遇到一個問題:對象丟失問題
我們看下面一種情況,當垃圾收集器掃描到下面情況時:
這時候應用程序執行了以下操作:
這樣,對象的狀態圖變成如下情形:
這時候垃圾收集器再標記掃描的時候就會下圖成這樣:
很顯然,此時C是白色,被認為是垃圾需要清理掉,顯然這是不合理的。那麼我們如何保證應用程序在運行的時候,GC標記的對象不丟失呢?有如下2中可行的方式:
在插入的時候記錄對象
在刪除的時候記錄對象
剛好這對應CMS和G1的2種不同實現方式:
在CMS採用的是增量更新(Incremental update),只要在寫屏障(write barrier)里發現要有一個白對象的引用被賦值到一個黑對象 的欄位里,那就把這個白對象變成灰色的。即插入的時候記錄下來。
在G1中,使用的是STAB(snapshot-at-the-beginning)的方式,刪除的時候記錄所有的對象,它有3個步驟:
這樣,G1到現在可以知道哪些老的分區可回收垃圾最多。 當全局並發標記完成後,在某個時刻,就開始了Mix GC。這些垃圾回收被稱作「混合式」是因為他們不僅僅進行正常的新生代垃圾收集,同時也回收部分後台掃描線程標記的分區。混合式垃圾收集如下圖:
混合式GC也是採用的復制的清理策略,當GC完成後,會重新釋放空間。
至此,混合式GC告一段落了。下一小節我們講進入調優實踐。
MaxGCPauseMillis調優
前面介紹過使用GC的最基本的參數:
前面2個參數都好理解,後面這個MaxGCPauseMillis參數該怎麼配置呢?這個參數從字面的意思上看,就是允許的GC最大的暫停時間。G1盡量確保每次GC暫停的時間都在設置的MaxGCPauseMillis范圍內。 那G1是如何做到最大暫停時間的呢?這涉及到另一個概念,CSet(collection set)。它的意思是在一次垃圾收集器中被收集的區域集合。
Young GC:選定所有新生代里的region。通過控制新生代的region個數來控制young GC的開銷。
Mixed GC:選定所有新生代里的region,外加根據global concurrent marking統計得出收集收益高的若干老年代region。在用戶指定的開銷目標范圍內盡可能選擇收益高的老年代region。
在理解了這些後,我們再設置最大暫停時間就好辦了。 首先,我們能容忍的最大暫停時間是有一個限度的,我們需要在這個限度范圍內設置。但是應該設置的值是多少呢?我們需要在吞吐量跟MaxGCPauseMillis之間做一個平衡。如果MaxGCPauseMillis設置的過小,那麼GC就會頻繁,吞吐量就會下降。如果MaxGCPauseMillis設置的過大,應用程序暫停時間就會變長。G1的默認暫停時間是200毫秒,我們可以從這里入手,調整合適的時間。
其他調優參數
避免使用以下參數:
避免使用 -Xmn 選項或 -XX:NewRatio 等其他相關選項顯式設置年輕代大小。固定年輕代的大小會覆蓋暫停時間目標。
觸發Full GC
在某些情況下,G1觸發了Full GC,這時G1會退化使用Serial收集器來完成垃圾的清理工作,它僅僅使用單線程來完成GC工作,GC暫停時間將達到秒級別的。整個應用處於假死狀態,不能處理任何請求,我們的程序當然不希望看到這些。那麼發生Full GC的情況有哪些呢?
並發模式失敗
G1啟動標記周期,但在Mix GC之前,老年代就被填滿,這時候G1會放棄標記周期。這種情形下,需要增加堆大小,或者調整周期(例如增加線程數-XX:ConcGCThreads等)。
晉升失敗或者疏散失敗
G1在進行GC的時候沒有足夠的內存供存活對象或晉升對象使用,由此觸發了Full GC。可以在日誌中看到(to-space exhausted)或者(to-space overflow)。解決這種問題的方式是:
巨型對象分配失敗
當巨型對象找不到合適的空間進行分配時,就會啟動Full GC,來釋放空間。這種情況下,應該避免分配大量的巨型對象,增加內存或者增大-XX:G1HeapRegionSize,使巨型對象不再是巨型對象。
由於篇幅有限,G1還有很多調優實踐,在此就不一一列出了,大家在平常的實踐中可以慢慢探索。最後,期待java 9能正式發布,默認使用G1為垃圾收集器的java性能會不會又提高呢?
G1處理和傳統的垃圾收集策略是不同的,關鍵的因素是它將所有的內存進行了子區域的劃分。
總結
G1是一款非常優秀的垃圾收集器,不僅適合堆內存大的應用,同時也簡化了調優的工作。通過主要的參數初始和最大堆空間、以及最大容忍的GC暫停目標,就能得到不錯的性能;同時,我們也看到G1對內存空間的浪費較高,但通過**首先收集盡可能多的垃圾(Garbage First)的設計原則,可以及時發現過期對象,從而讓內存佔用處於合理的水平。
參考鏈接:
https://juejin.cn/post/6859931488352370702
https://blog.csdn.net/qq_39276448/article/details/104470796
『叄』 JVM的垃圾演算法有哪幾種
一、垃圾收集器概述
如上圖所示,垃圾回收演算法一共有7個,3個屬於年輕代、三個屬於年老代,G1屬於橫跨年輕代和年老代的演算法。
JVM會從年輕代和年老代各選出一個演算法進行組合,連線表示哪些演算法可以組合使用
二、各個垃圾收集器說明
1、Serial(年輕代)
年輕代收集器,可以和Serial Old、CMS組合使用
採用復制演算法
使用單線程進行垃圾回收,回收時會導致Stop The World,用戶進程停止
client模式年輕代默認演算法
GC日誌關鍵字:DefNew(Default New Generation)
圖示(Serial+Serial Old)
7、G1
G1收集器由於沒有使用過,所以從網上找了一些教程供大家了解
並行與並發
分代收集
空間整合
可預測的停頓