2016-05-05 24 views
0

我在試圖追蹤這個OutOfMemoryError時遇到了很糟糕的情況,我非常感謝您的幫助。我的應用程序被分成了體系結構部分和一個模塊,這些模塊公開了一些基本的REST WS和由Hibernate製作的數據庫CRUD操作。主體系結構具有記錄和管理屬性和配置的唯一角色(所有這些都由Spring處理)。追蹤OutOfMemoryError

應用程序沒有做任何事情,但仍然在2-3熱重新部署與Tomcat 7後我得到一個OutOfMemoryError。我做了一個堆轉儲與VisualVM的打開了它,這是我所看到的:

enter image description here

正如你所看到的,我有很多串,的char []和byte []左右。真正操縱這種數據的唯一類是它是一個Servlet過濾器只有這樣的記錄:

@Override 
public void doFilter(ServletRequest request, ServletResponse response, 
     FilterChain chain) throws IOException, ServletException { 

     HttpServletRequest httpServletRequest = (HttpServletRequest) request; 
     HttpServletResponse httpServletResponse = (HttpServletResponse) response; 

     Map<String, String> requestMap = this 
       .getTypesafeRequestMap(httpServletRequest); 
     BufferedRequestWrapper bufferedRequest = new BufferedRequestWrapper(
       httpServletRequest); 
     BufferedResponseWrapper bufferedResponse = new BufferedResponseWrapper(
       httpServletResponse); 

     final StringBuilder logMessage = new StringBuilder(
       "REST Request - ").append("[HTTP METHOD:") 
       .append(httpServletRequest.getMethod()) 
       .append("] [PATH INFO:") 
       .append(httpServletRequest.getRequestURI()) 
       .append("] [REQUEST PARAMETERS:").append(requestMap) 
       .append("] [REQUEST BODY:") 
       .append(bufferedRequest.getRequestBody()) 
       .append("] [REMOTE ADDRESS:") 
       .append(httpServletRequest.getRemoteAddr()).append("]"); 
     long startTime = System.currentTimeMillis(); 
     chain.doFilter(bufferedRequest, bufferedResponse); 
     long elapsed = System.currentTimeMillis() - startTime; 
     logMessage.append(" [RESPONSE:") 
       .append(bufferedResponse.getContent()) 
       .append("] [ELAPSED TIME:").append(elapsed).append("ms]"); 
     log.debug(logMessage.toString()); 
} 

當記錄器是不是這個原因,可能是由於某些春/休眠/ Tomcat的/我不知道的一些圖書館?

如果您需要其他任何東西,比如Spring配置,請隨時詢問。

謝謝!

+0

什麼是你的tomcat內存設置(Xmx,PermSize)? –

+0

當Tomcat作爲應用程序服務器啓動時,是否嘗試爲Web應用程序分配更多內存?還試圖找出是否「一個支配者對象」創建並持有許多引用(我在Hibernate是原因時遇到過一個案例) – dumitru

回答

0

該問題與JEE webapps的熱重新部署有關。不是在Tomcat中,而是在任何JEE Servlet容器中。

有在這裏討論一個很好的解釋:

What makes hot deployment a "hard problem"?

+1

除了僅作爲鏈接回答之外,該博文顯得相當過時。具體來說,它要求設置Java 8中不再存在的JVM參數,並且Java 7已超過一年現已終止。 – meriton

0

正如你所看到的,我有很多串,的char []和byte []左右。唯一真正處理這種數據的類是記錄器,它是一個servlet-過濾器

這真的很難相信。 hibernate實體不包含單個字符串,HTTP請求永遠不會存儲在char []中,響應永遠不會被緩衝,...

字符串是一種無處不在的數據類型,幾乎您的類路徑中的每個庫都將使用它們廣泛而言,訣竅在於找出哪個庫泄漏了它們,以及爲什麼。

爲了有效地分析堆轉儲,您應該使用一個不僅列出有多少對象的工具,還要分析對象引用的圖形以找出哪些對象正在使這些字符串保持活動狀態。大多數商業內存配置文件都做得很好。除此之外,開源Eclipse Memory Analyzer也不錯。自從我上次使用它以來已經有一段時間了,但是對於最後一次內存泄漏,MAT的標準泄漏可疑報告正確識別了導致OutOfMemoryError的對象。