OutOfMemoryError 발생
- 작성자 :
- 장*수
- 작성일 :
- 2013-05-14 09:44:54
- 조회수 :
- 2,257
- 구분 :
- 실행환경
- 진행상태 :
- 완료
Q
안녕하세요? 장명수입니다.
eGovframework 1.0에 jeus5를 연동하여 사이트를 운영하고 있습니다.
얼마전 서버에서 OutOfMemoryError가 발생하였는데 관련 java heap 덤프를 떠본 결과
아래와 같은 분석이 도출되었습니다.
1) Problem Suspect 1
OutOfMemoryError 의 원인으로 com.ibatis.sqlmap.engine.mapping.statement.RowHandlerCallback Object 가 존재하며 약 1360 MB (63%) 의Memory를 사용하고 있습니다.
이는 com.ibm.oti.vm.BootstrapClassLoader 에 의하여 Loading 된 java.lang.Object[58837] 배열을 Reference 하고 있으며 세부 내용을 보면,
약 30 KB 씩 58,837개의 egovframework.rte.psl.dataaccess.util.EgovMap 이 존재합니다.
2) Problem Suspect 2
OutOfMemoryError 의 원인으로 com.ibm.oti.vm.BootstrapClassLoader 에 의하여 Loading 된 31개의 java.util.LinkedList$Entry Object 가 존재하며 약 456 MB (21%) 의Memory를 사용하고 있습니다.
1개의 java.util.LinkedList$Entry Object 세부 내용을 보면, org.apache.commons.dbcp.PoolingConnection Reference 하고 있으며 하위에519개의 oracle.jdbc.driver.T4CPreparedStatement 이 존재합니다.
3) 결론
결과적으로 OutOfMemoryError 의 분석 결과는 Application 에서 Memory 를 과 점유하는 것으로
인하여 발생한 것으로 판단됩니다.
제가 궁금한 것은 아래 와 같습니다
1) jeus의 커넥션을 안쓰고 자체 jdbc pool를 쓰는데 그것이 문제인지?
2) 설정 값 컨트롤이 아니라 프로그램 상의 문제를 찾아봐야 하는지?
3) 프로그램 상의 문제라면 어떤 부분을 중안을 둬야 하는지?
(비지니스 보단 프레임웍 구조에서 디버깅 포인트)
좋은 하루되세요~
-- dpcp 설정
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="oracle.jdbc.OracleDriver"/>
<property name="url" value="URL"/>
<property name="username" value="USERNAME"/>
<property name="password" value="PASSWORD"/>
<property name="defaultAutoCommit" value="false"/>
<property name="poolPreparedStatements" value="true"/>
<property name="initialSize" value="20"/>
<property name="maxIdle" value="30"/>
<property name="maxActive" value="50"/>
<property name="maxWait" value="10000"/>
<property name="validationQuery" value="select 1 from dual"/>
<property name="testWhileIdle" value="true"/>
<property name="timeBetweenEvictionRunsMillis" value="60000"/>
</bean>
eGovframework 1.0에 jeus5를 연동하여 사이트를 운영하고 있습니다.
얼마전 서버에서 OutOfMemoryError가 발생하였는데 관련 java heap 덤프를 떠본 결과
아래와 같은 분석이 도출되었습니다.
1) Problem Suspect 1
OutOfMemoryError 의 원인으로 com.ibatis.sqlmap.engine.mapping.statement.RowHandlerCallback Object 가 존재하며 약 1360 MB (63%) 의Memory를 사용하고 있습니다.
이는 com.ibm.oti.vm.BootstrapClassLoader 에 의하여 Loading 된 java.lang.Object[58837] 배열을 Reference 하고 있으며 세부 내용을 보면,
약 30 KB 씩 58,837개의 egovframework.rte.psl.dataaccess.util.EgovMap 이 존재합니다.
2) Problem Suspect 2
OutOfMemoryError 의 원인으로 com.ibm.oti.vm.BootstrapClassLoader 에 의하여 Loading 된 31개의 java.util.LinkedList$Entry Object 가 존재하며 약 456 MB (21%) 의Memory를 사용하고 있습니다.
1개의 java.util.LinkedList$Entry Object 세부 내용을 보면, org.apache.commons.dbcp.PoolingConnection Reference 하고 있으며 하위에519개의 oracle.jdbc.driver.T4CPreparedStatement 이 존재합니다.
3) 결론
결과적으로 OutOfMemoryError 의 분석 결과는 Application 에서 Memory 를 과 점유하는 것으로
인하여 발생한 것으로 판단됩니다.
제가 궁금한 것은 아래 와 같습니다
1) jeus의 커넥션을 안쓰고 자체 jdbc pool를 쓰는데 그것이 문제인지?
2) 설정 값 컨트롤이 아니라 프로그램 상의 문제를 찾아봐야 하는지?
3) 프로그램 상의 문제라면 어떤 부분을 중안을 둬야 하는지?
(비지니스 보단 프레임웍 구조에서 디버깅 포인트)
좋은 하루되세요~
-- dpcp 설정
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="oracle.jdbc.OracleDriver"/>
<property name="url" value="URL"/>
<property name="username" value="USERNAME"/>
<property name="password" value="PASSWORD"/>
<property name="defaultAutoCommit" value="false"/>
<property name="poolPreparedStatements" value="true"/>
<property name="initialSize" value="20"/>
<property name="maxIdle" value="30"/>
<property name="maxActive" value="50"/>
<property name="maxWait" value="10000"/>
<property name="validationQuery" value="select 1 from dual"/>
<property name="testWhileIdle" value="true"/>
<property name="timeBetweenEvictionRunsMillis" value="60000"/>
</bean>
A
안녕하세요. 장명수님.
1번의 현상은 일반적으로 DB 정보 결과를 많이 가져올 때에 발생되는 현상입니다. DB의 결과 레코드를 EgovMap(resultClass)로 넘어 받는 경우인데, 일부 데이터 조회 처리 상에 페이징 처리가 되지 않은 부분이 있으신 것 같습니다.
해당 부분을 찾으셔서 페이징 처리 방식으로 전환하셔야 합니다.
2번째의 경우도 query가 호출될 때에 사용되는 PreparedStatement 객체인데, 이 경우는 GC가 수행된 후에도 계속 남아 있는지 확인이 필요할 것 같습니다.
일반적인 상황에서 GC로 처리되지 않는 문제라면, DBCP 자체의 문제이기 때문에 프레임워크 부분에서 반드시 확인이 필요할 것 같습니다.
궁금하시다고 올려주신 부분은
1) 자체 방식보다는 JEUS DataSource 권장합니다. WAS 상의 모니터링이 가능하고, DB 연결정보를 WAS에서 감추는 효과가 있기 때문입니다.
2) 1번째 경우는 프로그램 상의 문제입니다.
3) Thread 상에 현재 돌고 있는 Controller로 페이징 처리를 하지 않는 query를 찾아보시면 되실 것 같습니다.
그럼, 즐거운 하루되십시오.
감사합니다.
1번의 현상은 일반적으로 DB 정보 결과를 많이 가져올 때에 발생되는 현상입니다. DB의 결과 레코드를 EgovMap(resultClass)로 넘어 받는 경우인데, 일부 데이터 조회 처리 상에 페이징 처리가 되지 않은 부분이 있으신 것 같습니다.
해당 부분을 찾으셔서 페이징 처리 방식으로 전환하셔야 합니다.
2번째의 경우도 query가 호출될 때에 사용되는 PreparedStatement 객체인데, 이 경우는 GC가 수행된 후에도 계속 남아 있는지 확인이 필요할 것 같습니다.
일반적인 상황에서 GC로 처리되지 않는 문제라면, DBCP 자체의 문제이기 때문에 프레임워크 부분에서 반드시 확인이 필요할 것 같습니다.
궁금하시다고 올려주신 부분은
1) 자체 방식보다는 JEUS DataSource 권장합니다. WAS 상의 모니터링이 가능하고, DB 연결정보를 WAS에서 감추는 효과가 있기 때문입니다.
2) 1번째 경우는 프로그램 상의 문제입니다.
3) Thread 상에 현재 돌고 있는 Controller로 페이징 처리를 하지 않는 query를 찾아보시면 되실 것 같습니다.
그럼, 즐거운 하루되십시오.
감사합니다.