2011-10-07 3 views
1

하나씩 1000000 개의 레코드가있는 배치 프로세스가 있습니다. 각 레코드에는 자체 자식 테이블이 있습니다. Spring 2.5.6, Hibernate, JPA를 사용하고있다. 그러나 1 시간 후에 그것은 기억을 잃게됩니다. 아무도 내 응용 프로그램에서 무엇이 잘못 될 수 있다고 제안 할 수 있습니까?Spring + Hibernate + JPA에서 일괄 처리 프로세스가 메모리 부족 상태가 됨

Public void processFeeds(List<Objects> feeds){ 

     for(Feed feed : feeds){ 
     Feed feed=getDAOMainFeedService().persist(feed); 

     //Saving the child information 
     if(feed.getID()>0) { 
      for(Address address : feeds.getAddress()){ 
       getDAOAddressService().persist(feed.getID,address); 
     } 

     for(PersonalInfo pi: feeds.getPersonalInfo){ 
       getDAOPIService().persist(feed.getID,pi); 
     } 
    } 
} 

} 

//service Class code: 
public class MainFeedServiceDAOImpl extends JpaDaoSupport implements IVehYmmRevDAO 
public Feed persist(Feed feed) 
    { 


     try 
     { 
      getJpaTemplate().persist(feed); 
      feed=getJpaTemplate().merge(feed); 
      getJpaTemplate().flush(); 

      return feed; 
     } 
     catch (Exception exception) 
     { 
      logger.error("Persit failed", 
        exception); 
      throw new DatabaseServiceException(
        "Persit failed", exception); 
     } 
    } 

} 

다른 DAO 클래스는 또한 상기 데이터베이스 서비스 층으로의 스프링을 사용하여 주입되고, 동일한 MainFeedServiceDAOImpl 구현을 가지고 : 여기서

코드이다. 몇 가지 제안을하십시오.

+0

James DW 님의 답변은 아래 사항에 매우 중요합니다. 내 reccomandation하지만 일괄 작업에 대한 최대 절전 모드 (또는 다른 ORM) 도랑 것입니다, 당신의 메모리 문제를 해결하더라도, 당신은 여전히 ​​다른 사람과 충돌거야. JDBC 만 사용하십시오. –

답변

4

삽입중인 모든 개체가 세션에 남아 있기 때문에 프로그램의 메모리가 부족한 이유는 다음과 같습니다. 때때로 제거해야합니다.

나는 이런 식으로 계속 방법을 변경할 것입니다 : 당신이 바로 매핑 및 계곡이있는 경우 비록

public void persist(List<Feed> feeds) 
{ 
    int count = 0; 
    try 
    { 
     for (Feed feed : feeds) { 
      getJpaTemplate().persist(feed); 
      if (count % 10000 == 0) { 
       getJpaTemplate().flush(); 
       getJpaTemplate().getEntityManager().clear(); 
      } 
      count++; 
     }    
    } 
    catch (Exception exception) 
    { 
     logger.error("Persist failed", exception); 
     throw new DatabaseServiceException("Persist failed", exception); 
    } 
} 

http://docs.jboss.org/hibernate/core/3.3/reference/en/html/batch.html#batch-inserts

당신은, 당신의 주소와 개인 정보 객체에 대해 같은 패턴을 따를 수 그 비트를 전혀 할 필요가 없을 수도 있습니다.

+0

10000은 내 의견으로는 더 좋을 것입니다. 그렇지 않으면 표결하다 – MarianP

0

피드를 계속 유지하기위한 호출을 일괄 처리하는 것이 도움이되지만 OOME 발생 만 지연됩니다. 시스템이 더 많은 수의 피드를 처리해야하는 날은 그것이 지속 단계에 이르기 전에 OOME으로 실행됩니다. 일괄 처리 논리는 피드가 지속되고 시스템에 입력되는 장소에 추가되어야하므로 어느 시점에서나 메모리에있는 최대 객체 수를 알 수 있습니다.