java.lang.OutOfMemoryErrorの発生から原因特定まで
java.lang.OutOfMemoryErrorの発生
現在1日に100人くらいの人が利用しているのだけれど、1日〜2日程度動かすと以下のエラーを吐き出して応答が返ってこなくなる問題が発生
Jul 23, 2011 9:40:51 AM com.sun.jersey.spi.container.ContainerResponse mapMappableContainerException SEVERE: The exception contained within MappableContainerException could not be mapped to a response, re-throwing to the HTTP container java.lang.OutOfMemoryError: Java heap space at com.sun.org.apache.xerces.internal.util.XMLStringBuffer.append(XMLStringBuffer.java:205) at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.refresh(XMLDocumentScannerImpl.java:1522) at com.sun.org.apache.xerces.internal.impl.XMLEntityScanner.invokeListeners(XMLEntityScanner.java:2070) at com.sun.org.apache.xerces.internal.impl.XMLEntityScanner.skipSpaces(XMLEntityScanner.java:1515) at com.sun.org.apache.xerces.internal.impl.XMLDTDScannerImpl.skipSeparator(XMLDTDScannerImpl.java:2056) at com.sun.org.apache.xerces.internal.impl.XMLDTDScannerImpl.scanDecls(XMLDTDScannerImpl.java:2032) at com.sun.org.apache.xerces.internal.impl.XMLDTDScannerImpl.scanDTDExternalSubset(XMLDTDScannerImpl.java:320) at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$DTDDriver.dispatch(XMLDocumentScannerImpl.java:1203) at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$DTDDriver.next(XMLDocumentScannerImpl.java:1090) at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(XMLDocumentScannerImpl.java:1003) at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:648) at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:140) at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:511) at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:808) at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:737) at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:119) at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1205) at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:522) at org.dom4j.io.SAXReader.read(SAXReader.java:465) at org.hibernate.util.xml.MappingReader.readMappingDocument(MappingReader.java:75) at org.hibernate.cfg.Configuration.add(Configuration.java:513) at org.hibernate.cfg.Configuration.add(Configuration.java:509) at org.hibernate.cfg.Configuration.add(Configuration.java:689) at org.hibernate.cfg.Configuration.addResource(Configuration.java:774) at org.hibernate.cfg.Configuration.parseMappingElement(Configuration.java:2317) at org.hibernate.cfg.Configuration.parseSessionFactory(Configuration.java:2283) at org.hibernate.cfg.Configuration.doConfigure(Configuration.java:2263) at org.hibernate.cfg.Configuration.doConfigure(Configuration.java:2216) at org.hibernate.cfg.Configuration.configure(Configuration.java:2131) at org.hibernate.cfg.Configuration.configure(Configuration.java:2110)
原因の調査
ヒープ領域の問題のようなので、Eclipse Memory Analyzerを使用して原因を調べる
jpsコマンドでプロセスIDを確認
# jps 4089 Jps 12131 jar
jmapコマンドでヒープをダンプ
# jmap -dump:format=b,file=(出力ファイル名) (プロセスID)
Memory Analyzer for Eclipse IDEを取得
以下のサイトから入手。
Eclipse Memory Analyzer Open Source Project
既にダンプを取得しているのでEclipseのプラグインではなくRPC版を使用する。
任意の場所に展開したら「MemoryAnalyzer.exe」を起動
ファイルを開く
「File」->「Open Heap Dump...」から先程のファイルを選択
dominator treeを開く
「Open Dominator Tree for entire heap.」というボタンがあるので押す。
「Retained Heap」列でソートしてサイズの大きなクラスを展開していく。
こんな感じ。
念のため一日置いて再度取得した結果。
どうやらHibernateのSessionFactoryObjectFactoryクラスが原因みたい。