java技術研究

          統(tǒng)計

          留言簿(3)

          閱讀排行榜

          評論排行榜

          關于hibernate導致tomcat內(nèi)存暴漲,頁面反應速度減慢(轉)

          2012年6月23日

          今天追蹤一個關于頁面內(nèi)存暴漲,頁面響應過慢的問題。花了4個多小時,總算找到問題出在哪了。

          一、問題描述

          最近我們在一臺獨享服務器上搭建了Tomcat6.0.19環(huán)境,發(fā)現(xiàn)訪問首頁時,內(nèi)存暴漲,一直不退。每次刷新內(nèi)存增加近10M。一個人狂刷新一分鐘就可以把tomcat搞死機。

          然后,找各種辦法解決問題。整了幾天,每天中午輪流監(jiān)控Tomcat服務器,發(fā)現(xiàn)它掛了后就重啟。累壞了。

          每天到google上面搜索答案,有人說是程序的問題,程序內(nèi)存泄露。甚至問到“有沒有數(shù)據(jù)庫沒有釋放”、“有沒有使用死循環(huán)”、有沒有寫“System.gc()自動釋放內(nèi)存”、有沒有“在Service層查詢時使用all()方法,查處了所有記錄”。等等。

          而我一直不承認程序有問題。理由是:我們曾經(jīng)將這個程序在租用的2個虛擬主機中用了近1個月。不斷維護,最后達到一個星期沒有出現(xiàn)一個異常的情況。

          二、問題分析(關于tomcat內(nèi)存溢出問題)

          分析Tomcat死機的日志,發(fā)現(xiàn)是內(nèi)存耗盡。

          大致有這么一段,PSPermGen total   86016K   used 86015K   

          到網(wǎng)上搜了一下,明白了jvm內(nèi)存分類。然后配置內(nèi)存,讓tomcat自動回收jvm內(nèi)存。

          當然,配置過程也遇到了很多問題,花了一天多。問題是網(wǎng)上的很多人都是抄來抄去,要在一大堆垃圾中選出精品不容易呀。

          配了一天都只起到一定作用。比如:給tomcat設置較大內(nèi)存后,tomcat可以承受到2.19G。只是再刷新就可以把他整崩潰。

          最后,請了幾個牛人幫忙,一個牛人凌晨幫我們看tomcat配置。問我們,是否加了,-server參數(shù)。最后,我同事加上了-server參數(shù)。 然后,回去睡覺了,發(fā)現(xiàn)java.exe內(nèi)存真的能回收了。很多問題也解決了。

          我們配置如下:(將tomcat6的安裝版卸載,換成綠色版)

          在catalina.bat的@echo off下面添加(就是第二行)

          set JAVA_OPTS=-server -Xms512m -Xmx1024m -XX:MaxNewSize=512m -XX:MaxPermSize=256m 

          在startup.bat下面添加(讓tomcat的工具自動回收內(nèi)存)

          @echo off 
          set JAVA_OPTS=%JAVA_OPTS% 
          -Dcom.sun.management.jmxremote.port=1090 
          -Dcom.sun.management.jmxremote.ssl=false 
          -Dcom.sun.management.jmxremote.authenticate=false 
          -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager 
          -Djava.util.logging.config.file="%CATALINA_HOME%\conf\logging.properties"

          三、問題分析(關于頁面反應速度異常)

          我們的首頁顯示餐館的信息,主要根據(jù)用戶選擇地區(qū),然后將該地區(qū)的餐館列表和熱賣美食列表顯示出來。我們發(fā)現(xiàn)一個很奇怪的現(xiàn)象,訪問某一學校東校區(qū)時:

          8個餐館:Action執(zhí)行2063ms(獲取餐館列表:1220ms + 獲取熱賣美食:825ms)。

          然后換成其他校區(qū)分別為:

          3個餐館:Action執(zhí)行 51ms   (獲取餐館列表:29    +    獲取熱賣美食: 2)

          3個餐館:Action執(zhí)行 53ms   (32   + 1)

          4個餐館:Action執(zhí)行 90ms   (74    + 1)

          看到這個數(shù)據(jù),我就很納悶,怎么時間不成比例呢?

          于是,我將8個餐館刪掉4個對比。由于有外鍵關聯(lián),我必須要刪除其他的很多的。為了刪除一個餐館記錄,我必須刪除其他記錄多達6個表處,可見外鍵關系較為復雜。

          等我刪掉后,發(fā)現(xiàn)東校區(qū):

          4個餐館:Action執(zhí)行111ms(獲取餐館列表:53ms + 獲取熱賣美食:37ms)。

          我發(fā)現(xiàn)這個變化太明顯了吧。然后,我懷疑那四個餐館關聯(lián)了太多東西。我查詢出來的不僅僅是餐館,可能連帶查詢了另外的6個表的記錄。

          我就想到了是hbm.xml文件中設置lazy = "true"問題。

          通過測試,我發(fā)現(xiàn)是 餐館對應訂單時,one-to-many時,lazy = "true"。這個就很明顯了。

          查詢一個餐館,就把它的上百份訂單級聯(lián)查詢出來了,同時把所有菜品也級聯(lián)查詢出來了,把所有菜品分類都查詢出來了。

          而就東校區(qū)的這8家餐館訂單較多,其他校區(qū)由于剛開業(yè),訂單幾乎沒有。這下就可以解釋為什么東校區(qū)這么耗時間(當然也耗內(nèi)存)。

          然后,我將hbm.xml的所有l(wèi)azy="true"全部去掉,恢復數(shù)據(jù)庫數(shù)據(jù)。

          東校區(qū)結果如下:

          8個餐館:Action執(zhí)行25ms(獲取餐館列表:3ms + 獲取熱賣美食:8ms)。

          四、結論:

                  lazy="false"使用時要慎重。例如:對與1:1的情況,使用直接影響不大,對于1:n情況就要慎重了。尤其是n成百上千時,問題就相當嚴重了。我建議最好不用。

          第一次,配置和管理服務器,收獲真大呀。對我以后的編程風格都造成了深遠的影響。我會注意服務器的時間和空間效率問題。

          當然測試方法比較土。先將服務器正常上線后,我會學著使用JMeter和roadrunner的工具做壓力測試,配置好服務器。

          忙里偷閑!記錄下來!


          轉自
          http://www.cnblogs.com/pyrmkj/archive/2012/06/23/2559375.html


          posted on 2012-08-14 22:14 小秦 閱讀(3716) 評論(2)  編輯  收藏

          評論

          # re: 關于hibernate導致tomcat內(nèi)存暴漲,頁面反應速度減慢(轉) 2016-03-30 13:49 水月

          在startup.bat下面添加(讓tomcat的工具自動回收內(nèi)存)

          @echo off
          set JAVA_OPTS=%JAVA_OPTS%
          -Dcom.sun.management.jmxremote.port=1090
          -Dcom.sun.management.jmxremote.ssl=false
          -Dcom.sun.management.jmxremote.authenticate=false
          -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager
          -Djava.util.logging.config.file="%CATALINA_HOME%\conf\logging.properties"

          linux下也是第二行加上這個?  回復  更多評論   

          # re: 關于hibernate導致tomcat內(nèi)存暴漲,頁面反應速度減慢(轉) 2016-03-30 20:19 小秦

          @水月 你要遇到內(nèi)存問題跟這個配置沒有關系,這個問題是因為設置成 lazy="false"引起的,會把不需要查詢的數(shù)據(jù)都查詢出來導致的。  回復  更多評論   


          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導航:
          博客園   IT新聞   Chat2DB   C++博客   博問  
           
          主站蜘蛛池模板: 大庆市| 清镇市| 南开区| 张家口市| 靖州| 诏安县| 资源县| 革吉县| 江口县| 泸州市| 从化市| 江华| 东乌珠穆沁旗| 衡东县| 萝北县| 鄂托克旗| 沈丘县| 东丰县| 吉安县| 吴桥县| 曲水县| 永修县| 彰武县| 乡城县| 九江市| 临潭县| 宜宾县| 顺义区| 黄龙县| 上犹县| 柳州市| 中卫市| 玉环县| 博白县| 华宁县| 宽甸| 融水| 塘沽区| 三江| 敦煌市| 波密县|