2016-10-18 63 views
3

Java 응용 프로그램을 연중 무휴로 실행 중이며, MySQL 서버와 TimerTask (Akka를 실행 중입니다)에 연결되어 있습니다. 1 주 또는 그 이하의 작업 후에 OutOfMemoryError를 실행 중이고 힙 덤프는 4 백만 개가 넘는 문자열로 LinkedHashMap을 보여 주며 800MB의 힙을 사용하는 java.io.DeleteOnExitHook의 GC 루트를가집니다.DeleteOnExitHook에서 메모리 누수가 발생했습니다.

모든 문자열은 /tmp/jar_cachexxxx.tmp

이 문제 같은 것이 오픈 JDK 런타임 환경 (1.8.0_101-B13를 구축) 실행하는 두 기계에 일치합니다. JDBC 드라이버는 maven "mysql-connector-java"버전 5.1.38에서 제공되는 것으로, 연결 풀 BoneCP, 버전 0.8.0을 사용하고 있습니다.

누구나이 누출에 대해 알고 있나요?

업데이트 - 우리는 프로젝트의 컴파일러를 변경 한 후 문제가 해결 5/12/16

. 우리는 eclipse jar creator가 jar 캐시와 관련이있는 유일한 것이라는 것을 알아 차 렸습니다. 그래서 maven을 사용하여 프로젝트를 컴파일 한 후에 메모리 누수가 사라졌습니다.

+0

당신이 데이터베이스를 액세스하는 방법에 대해 더 많은 정보를 제공 할 수를 Akka를 사용하고 있습니까? Java.io.File.deleteOnExit()를 호출하고 있습니까? 얼마나 많은 문자열을 보았습니까? "/tmp/jar_cachexxxx.tmp"처럼 보입니까? 빨간 새끼일지도 모릅니다. 이러한 문자열이 1000 개라도 800MB를 차지하지 않습니다. 다른 문자열을 찾으십시오. – joseph

+0

"/tmp/jar_cachexxxx.tmp"와 같은 문자열을 어떻게 찾았습니까? 800MB는 약 800MB/30 바이트 = 26,666,666 개의 문자열이 필요하다는 것을 의미합니다. – joseph

답변

0

응용 프로그램의 일부가 File.deleteOnExit을 사용 중입니다. 그러나 애플리케이션이 존재하지 않기 때문에 Java는 마침내 종료 될 때 삭제되어야하기 때문에 모든 파일을 추적해야합니다. 디버거를 사용하여 응용 프로그램의 어느 부분을 찾은 다음 대안을 찾으십시오.

5

이것은 오래 동안 잘 알려진 버그로, 수년 동안 Sun/Oracle MANY 시간에보고되었습니다. 현재 버그 번호는 JDK-4872014입니다.

exit-delete-API를 사용할 때마다 File은 HashMap에 저장됩니다. 장기 실행 서버에서 코드가 의도적으로 종료되는 경우는 드물기 때문에 많은 임시 파일로이 작업을 수행하면 맵이 제한없이 커질 수 있습니다.

기본적으로 API는 장기 실행 서버에서는 사용할 수 없으므로 API를 사용할 수 없습니다. 이 기능이 필요한 경우 직접 구현해야하며 삭제할 수있는 파일을 알 수있는 방법으로 일정에 따라 정리를 실행해야합니다.

+0

JVM의 버그가 아니어야합니다. JVM은 응용 프로그램이 종료 될 때 제거해야하는 모든 파일을 기억해야합니다. 나는 그것이 여전히 열려있는 이슈 인 것에 놀랐다. – joseph

+1

아마도 맞을 것입니다. 이 API는 이상적으로 종료되지 않는 프로세스를위한 것이 아닙니다. –

0

"/tmp/jar_cachexxxx.tmp"파일의 경로 이름에 실마리가 있습니다.

분명히 URLClassloader가 원격 JAR 파일을 다운로드하여로드 할 때 생성됩니다. 수백만 개의 문자열이 있다면 너무 자주 그렇게한다는 의미입니다.

관련 문제