2017-12-23 14 views
0

최대 절전 모드를 사용하여 MySQL 데이터베이스를 쿼리하여 특정 여행의 모든 ​​세그먼트를 찾습니다. 예를 들어 A-> D에서 A-> B, B-> C, C-> D 세그먼트가있을 수 있습니다.가비지 컬렉션 오버 헤드 한도 - 최대 절전 모드

이 쿼리는 매우 자주 실행되며 매우 빠르게 완료됩니다. 데이터베이스는 성능이 매우 좋은 방법으로 인덱싱됩니다. 다음과 같이 쿼리에 대한 코드는 다음과 같습니다 dailyJournies이 클래스의 initilisation에 설정되고 다시 변경되지 않습니다

public List<Segment> getSegmentsForUID(String trainUid) { 
    Query segmentQuery = session.createQuery("select segment from Segment segment inner join segment.journey as journey where segment.journey " + 
              "in (:journies) and journey.trainUid = '" + trainUid + "'"); 
    segmentQuery.setParameterList("journies", dailyJournies); 
    queryCount++; 
    return segmentQuery.getResultList(); 
} 

.

제 문제는이 쿼리를 여러 번 (일반적으로 2,000 개에서 3,000 개까지의 쿼리를 수행 한 후) 항상 Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceededreturn segmentQuery.getResultList(); 줄에 넣었다는 것입니다.

초기화 이후에이 클래스의 다른 부분을 다루지 않으므로이 줄에서 예외가 항상 throw되기 때문에 다른 곳에서는 문제가 있다고 상상할 수 없습니다.

조금 파고 들었을 때 생각했던 원래의 생각은 Hibernate 세션이 너무 커져서 1,000 개의 쿼리가 끝날 때마다 세션을 닫고 다시 시작하기 시작했지만 아무런 차이가 없었습니다. 또한 다음 코드를 사용해 보았습니다.

Cache cache = session.getSessionFactory().getCache(); 
cache.evictAllRegions(); 

수동으로 세션 캐시를 지우는 데는 아무 것도하지 않았습니다.

다른 사람이 전에 이것을 보았습니까? 아니면 실종되었다는 것이 명백하게 드러났습니까?

+0

프로필 응용 프로그램; 당신이 붙잡고있는 것을 결정하십시오. –

+0

Netbeans의 @BoristheSpider 프로파일 링은 생존하는 세대가 시간이 지남에 따라 꾸준히 증가한다는 것을 보여줍니다. 객체 프로파일 러에서 char []가 가장 많은 메모리를 사용하고 있으며 시간이 지남에 따라 꾸준히 증가하는 것으로 나타났습니다. 다시 코드에 연결하는 데 사용할 수있는 다른 도구가 있습니까? – Tom

+1

문제와 관련이 없습니다. 문자열 처리를 사용해서는 안됩니다. 이미 명명 된 매개 변수를 사용하고 있습니다. 왜 'trainUid'에도 사용하지 않으시겠습니까? – the8472

답변

0

내가 전에 올바른 정보를 찾지 못했던 것 같습니다.

분명히 다른 사람들도 경험 한 문제입니다 (https://github.com/ow2-proactive/scheduling/issues/2870). 이 질문을 통해 비틀 거리는 사람들을위한

, 내 최대 절전 모드 설정 파일에 다음 두 줄을 추가하여 고정 :

<property name="hibernate.query.plan_cache_max_size">16</property> 
<property name="hibernate.query.plan_parameter_metadata_max_size">128</property> 

GitHub의에서 무엇을 제안했다된다. 나는이 문제가 세션을 유지하고 많은 쿼리에 대해 sessionFactory를 열어서 발생한다고 생각한다. 각 1,000 항목에 대해 새 sessionFactory를 만들어 문제를 해결할 수도 있지만이 솔루션은 더 깨끗해 보입니다.

+2

새로운 'SessionFactory'를 만들어 내지 않아야합니다. 매우 무거 우며 애플리케이션의 전체 라이프 사이클 동안 살아 있도록 설계되었습니다. 캐싱이라는 두 가지 어려운 문제 중 두 번째 문제가 발생한 것 같습니다. –

+0

@BoristheSpider 그 점을 명확히 해 주셔서 감사합니다. 세션을 닫고 다시 여는 것은 좋은 일이라고 생각합니다. – Tom

+1

예, 정확하게 - 세션은 가볍고 수명이 짧습니다. 일반적으로 하나의 "트랜잭션"(물리적 또는 논리적) 이상의 세션에 살아있는 세션은 반 패턴입니다. –

관련 문제