2012-12-16 4 views
1

PreparedStatements를 캐시하는 사내 DB 연결 풀로 작업하고 있습니다. 연결이 풀로 반환되면 캐시 된 문은 닫히지 않습니다. 이것들은 mySQL 드라이버에서 OutOfMemoryExceptions를 생성합니다. 그래서는 HashMap < 문자열,하는 SoftReference < PreparedStatement의 > >해당 GC 이전에 SoftReference로 저장된 PreparedStatements를 닫아야합니다.

에서의 PreparedStatement 캐시를 저장하기 위해 계획입니다 그러나 이것은 그들이 GC'd 전에 나를 문을 닫을 수 없습니다.

ReferenceQueue를 사용하는 것은 쓸모가 없으며, finalize 메소드가 권장되지 않는다는 것을 읽었습니다.

+2

PreparedStatement를 캐싱 할 때 메모리가 누출되는 것 외에 다른 결과가 있습니까? –

+0

PreparedStatments를 캐싱하면 데이터베이스를 사용할 때마다 데이터베이스에 한 번 왕복하는 것과 같은 이점이 있습니다.하지만 이점이 비용보다 중요한 이유는 확실하지 않습니다. 어쨌든 나를 위해 캐싱을 제거하는 것이 훨씬 더 복잡합니다 (많은 성능 테스트) 내가 제안하고있는 SoftReference 접근보다. – austindz

+0

PreparedStatement를 만들 때 DB 로의 왕복이 확실합니까? 나는 한 번도 본 적이 없다. 오직 사형에 처해있다. 마이크로 벤치 마크가 아닌 응용 프로그램의 글로벌 컨텍스트에서 이러한 최적화를 도입 할 때 실제로 예상되는 이점을 측정 했습니까? PreparedStatements의 생성은 실제로 핫스팟입니까? –

답변

1

finalize()가 무시 될 수 있습니다.

+0

자바가 매번 finalize()를 호출하지 않기 때문에 이것은 좋은 생각이 아닙니다. –

+0

@ ErdinçTaşkın OutOfMemoryException 전에 GC가 발생하고 GC가 이전 마무리 작업을해야한다는 것을 보장합니다. – EJP

0

Guava caches을 확인해야합니다. 퇴거시 softValues() 메서드 RemovalListener을 사용하여 PreparedStatement을 닫을 수 있습니다.

실제로 메모리를 오픈 PreparedStatement로 채우기를 원한다면, 또는 고정 캐시 크기를 사용하고 가장 최근에 사용되지 않은 항목을 제거하는 것이 더 나을 때 고려하십시오.

+0

RemovalListener는 정책으로 인해 값이 캐시에서 제거 된 경우에만 작동하며 GC에 메모리가 필요하기 때문에 작동하지 않습니다. 그렇지 않으면 ReferenceQueue와 같은 문제입니다. 명령문을 닫기에는 너무 늦습니다. 또한 리스너를 적시에 호출하기 위해 적극적으로 사용되는 캐시가 필요합니다 (여기에 해당되는 경우 또는 캐시가 쓸모 없지만 하중이 일정하지 않은 경우 모든 연결에 대해 보장되지는 않습니다). –

+0

PreparedStatement (또는 닫는 것이 필요한 모든 객체)는 SoftReferences를 사용하는 것이 아니라 명시 적 퇴거 정책과 만 작동합니다. 이는 참조가 참조 해제되기 전에 문을 닫아야한다는 알림을받는 유일한 방법입니다. SoftReferences를 사용하면 ReferenceQueue를 통해 너무 늦은 알림을받을 수 있습니다. GC 실행 중에 참조가 지워지고 응용 프로그램이 중간에 제어권을 회복하지 않고 메모리가 필요하다고 결정할 때 참조가 해제됩니다. –

관련 문제