2012-02-16 3 views
3

내 Java 응용 프로그램에서 메모리 사용에 문제가 있으며 가비지 수집기가이를 정렬하지 못하는 이유를 이해할 수 없습니다. 다음과 같이 코드는 다음과 같습니다개인 메서드 호출의 가비지 수집

public void foo() { 
    for(int i=0; i<50000; i++) { 
     bar(i); 
    } 
} 

private void bar(int i) { 
    LargeObject o = new LargeObject(); 
    ... 
    dao.save(o); 
} 

내 문제가 LargeObject의 인스턴스가 가비지 수집 받고되지 않습니다 - 이것은 내가 JProfiler와 함께 프로파일과 힙을 검토 한 결과를 식별 할 수 있습니다. LargeObject 인스턴스는 클래스 변수에 의해 참조되지 않으며 실제로는 bar() 외부의 아무 곳에서도 참조되지 않습니다. 나는 느낀 빨대에 쥐고 있지만 트랜잭션이 시작/끝나는 곳과 관련 될 수 있습니까? bar()을 공개로 변경하고 Propogation.REQUIRES_NEW에 주석을 달고 foo()의 특수 효과를 Propogation.NEVER으로 변경해 보았습니다.

DAO를 내부의 코드는 다음과 같습니다 : 나는 JProfiler와 활동의 참조로

public void save(LargeObject o) { 
    hibernateTemplate.getSessionFactory().getCurrentSession().saveOrUpdate(o); 
} 

가비지 콜렉션이 확실히 실행됩니다. foo()은 약 30 분, bar()은 36ms, 가비지 수집 스파이크는 대략 60 초마다 걸립니다.

왜 그들이 가비지 수집되지 않는지에 대한 질문에 대답하려면 - 시스템에서 LargeObject를 참조하는 것은 없지만 foo()이 실행 중일 때 힙에있는 인스턴스가 증가하는 것을 봅니다.

+0

은 어떻게 할 문제를 이해하는 데 도움이 될 수 있습니다 각 LargeObject에 대한 새로운 세션, 또는 삭제 세션을 사용 : 당신도 고려해야한다 인스턴스가 수집되지 않는다는 것을 알고 있습니까? 이것들이 크고 복잡한 물건이라면 무언가에 의해 참조되지 않는다는 것을 확실히 할 수 있습니까? 또한 가비지 컬렉터도 실행합니까? 긴밀한 루프에서 실행하면 GC가 어떤 작업을 수행하지 못할 수도 있습니다. – RQDQ

+0

전체 GC 동안 만 수집되는 큰 개체에 대해 뭔가를 기억하는 것 같습니다. – cHao

+0

comment line :'dao.save (o);' – Azodious

답변

4

분명히 JPA 제공 업체 (또는 dao.save() 뒤에 숨겨져있는 것이 무엇이든)에 의해 참조됩니다. 당신은 참조를 외부에 두었습니다. 그러므로 당신의 통제는 상실됩니다. 개인/공개 방법으로할지 여부는 중요하지 않습니다.

"DAO"에 대한 자세한 정보를 공유하고 싶을 수도 있습니다.

+0

당신의 의견을 보내 주셔서 감사합니다. - 최대 절전 모드가 그것을 유지할 수 있다고 생각하지 않았습니다. save 메소드의 코드를 보여주는 업데이트 된 질문을 참조하십시오. 전에 우연히 만났습니까? – James

2

루프가 모든 Large Objects 인스턴스를 캐시해야했던 고유 한 세션에 부담을 줄 수 있다고 @ MaDa의 답변에 추가했습니다. 세션이 저장 후 세척, 또는 그들이 Batch Processing에 절을 읽고

를 관련이없는 경우