最近用jprofile測試乙個比較大的工程,希望能找到一些程式執行的瓶頸。過去使用hibernate,很多人反映效率低。特別是懶載入關閉的時候,物件的持續生成最後會導致jvm直接outofmemory錯誤。目前使用ibatis,發現臨時物件還是特別多,一開始百思不解。通過使用jprofile以後,終於找到了原因所在。
物件引用關係:baseview ->instancemodel -> city
其中,baseview 引用了instancemode,而instancemode 引用了city物件,city物件是乙個比較簡單的物件,只有id、name、中文名稱等屬性。在工程實際使用環境中,instancemodel 是比較多的,可能會有數萬經常被使用。通過對jvm堆的觀察,發現每次instancemodel物件生成的時候,都會附帶出大量的city物件。由於一般應用中city的個數都有限,所以程式中專門對city物件作了快取。為什麼會產生大量city的臨時物件呢?
通過在jprofile中檢視堆的情況,可以很清楚的看到上述引用關係。這很正常啊?納悶中,反覆檢視堆、物件、引用關係等資訊,終於發現了線索。那就是,被引用的city物件中只有id值,沒有中文名稱等其他資訊。這就讓我們找到了突破口,通過與開發工程師的交談,被告知只使用了id值,沒有使用其他的屬性。於是我們找到ibatis載入baseview物件的對映檔案:
<
resultmapid=
"baseview"
class
="view"
>
…<
result
column
="citycode"
property
="instancemodel.city.id"
jdbctype
="numeric"
/>
resultmap
>
注意,在上面這個定義檔案中,載入view物件的時候,從同一張資料庫表中,載入了view所屬的city的**(id)。但是ibatis框架在達到這個目的的同時,生成了乙個臨時city物件,並把id賦了值。這就是原因!!
好了,原因找到了,優化的方案自然就出來了。只需要去掉instancemodel對city物件的引用,直接取city的id就行了!再次執行jprofile,發現不再生成大量的city臨時物件,優化的目的達到了。
結論:使用hibernate、ibatis等框架的時候,我們過於熱衷於物件引用的方便,忽視了這種方便的代價。有時候,我們只為了使用乙個簡單型別的資料,卻大量載入肥胖物件而不自知。然後抱怨框架效率低,有問題。其實回頭看看,良好的資料庫設計、良好的物件設計這些基本的東西,是任何框架都不能幫我們做的。同時感嘆jprofile這種強大工具給我們帶來的好處,讓我感覺又回到了dos debug 的時代。
mysql調優經驗
訪問量越來越大,mysql自然成為瓶頸,因此最近我一直在研究 mysql 的優化,第一步自然想到的是 mysql 系統引數的優化,作為乙個訪問量很大的 日20萬人次以上 的資料庫系統,不可能指望 mysql 預設的系統引數能夠讓 mysql執行得非常順暢。通過在網路上查詢資料和自己的嘗試,我認為以下...
GC調優經驗
ygc是最頻繁發生的,發生的概率是oldgc和fullgc的的10倍,100倍,甚至1000倍。同時younggc的問題也是最難定位的。這裡給出ygc定位三板斧 檢視伺服器swap io情況,如果伺服器發生swap,會嚴重拖慢gc效率,導致stw時間異常長,拉長介面響應時間,從而影響使用者體驗 推薦...
MYSQL一次調優經驗
前言 這是最近剛發生在公司的一次應用系統的mysql調優過程,事情的過程是這樣的 公司的乙個銷售系統,用的是mysql資料庫,在元旦的前夕突然就宕機了。差不多導致業務系統4個小時左右使用有問題 因為這個系統乙方公司尚未完全交付,所以資料庫的運維的工作,作為甲方也還未交接到我的手上,這個事情也是元旦過...