2013-08-29 1 views
3

먼저 작은 배경. SQL Server에서 데이터를 가져 오는 관리 소프트웨어에 대해 연구하고 있습니다. 나는 JPA을 사용하여 관리 소프트웨어 내에서 조작하기위한 테이블 인스턴스 인 Entity을 생성합니다 (지금은 이틀 동안 JPA만을 사용했습니다). 테스트로서, 아래 코드를 사용하여 18,500 행 (또는 abouts)의 가장 풍부한 테이블 (PeriodicalTable)의 개체를 저장하는 데 얼마나 많은 메모리가 차지 될지 테스트하고 성장 가능성이 높습니다.JPA 메모리 관리 문제

public static void main(String[] args) { 
    EntityManagerFactory emf = Persistence.createEntityManagerFactory("PersistenceDemoPU"); 
    EntityManager em = emf.createEntityManager(); 

    Query query = em.createQuery("SELECT p FROM PeriodicalTable p"); 
    //query.setMaxResults(7000); 
    List<PeriodicalTable> results = query.getResultList(); 
    PeriodicalTable storedPlayer; 

    for (int i = 0; i < results.size(); i++){ 
     storedPlayer = results.get(i); 
     System.out.println(storedPlayer.toString()); 
     if (i == (results.size()-1)){System.out.println("Total results: "+(i+1)); } 
    } 

    em.close(); 
    emf.close(); 
} 

위의 코드는 내가 512m에 -Xmx을 제기에도 불구하고 java.lang.OutOfMemoryError: Java heap space가 발생합니다. 이 소프트웨어가 실행될 컴퓨터에는 약 2GB의 RAM 만 있기 때문에 더 이상 메모리를 사용하고 싶지 않습니다. 이제 각각의 쿼리에 대해 .setMaxResults()을 사용할 수 있지만 (주석으로 볼 수 있듯이) 최종 제품에 모든 것을 표시해야하므로 이상적이지 않습니다.

그래서, 질문입니다. JPA를 사용하면서 테이블의 모든 엔티티에서 toString을 실행하는 메모리 효율적인 방법이 있습니까? 이러한 여러 가지 방법의 장단점은 무엇입니까? 나는 어쩌면 .toString()에 의해 전달 된 문자열 값 목록을 저장하는 것에 대해서 생각해 보았지만, 먼저 .getResultList()을 사용하지 않고 그 결과를 목록에 먼저 저장하는 방법을 생각할 수 없습니다.

편집 : 한 편으로서 Java Standard JPA를 사용하고 있으며 Hibernate 또는 ObjectDB 또는 그와 유사한 것을 조사하지 않았습니다. 그들의 사용이 필수적이지 않으면, 필자는 필요한 것보다 더 많은 기술에 대해 배우는 것을 피하려고합니다.

+0

PeriodicalTable에 대한 toString() 구현을 보여 주실 수 있습니까? –

+1

도움이 될 수 있습니다 - 페이지별로 페이지 읽기 : http://java-persistence-performance.blogspot.com/2011/06/how-to-improve-jpa-performance-by-1825.html –

+0

@Rob Blake -'public String toString() {return reference;}'참조는 단지 String입니다. –

답변

3

query.setMaxResults()query.setFirstResult()으로 결과 매김을 시도 할 수 있습니다. 그렇게하면 예를 들어 2500 행의 청크로 결과를로드 할 수 있습니다.

+0

'.setFirstResult()'는 행 번호 또는 기본 ID를 사용합니까? 이 테이블의 기본 ID는 모두 제 위치에 있습니다 (직접 설정하지 않았습니다). –

+0

결과를 고유하게 주문할 수 있습니까? 그렇게하면 잘 작동합니다. – Kayaman

+0

글쎄요, 기본 ID는 고유하지만 틈이 많이 있습니다. 숫자 사이의 점프, 길이가 다른 숫자의 숫자 등등 모두 괜찮습니다. 모든 논리가 방향을 잡기 어렵게 만듭니다. –

2

일반적으로 ORM은 대량의 데이터를로드하고 처리하기에 적합하지 않습니다. 구현이 얼마나 효율적이든 관계없이 ORM은 리플렉션에 크게 의존하므로 많은 메모리와 CPU를 사용합니다. 문서에서 볼 수 있듯이로드 - 수정 - 지속 시나리오를 위해 설계되었습니다. 많은 양의 데이터를로드하고 표시해야하는 경우 확실히 페이지 매김이 필요합니다.

0

PeriodicalTable 매핑과 지연로드 개체를 확인하십시오.

+0

필자가 지금까지 가지고있는 Entity 클래스에는 가져올 연관된 Entity 객체가 없습니다. 그것이 당신이 의미하는 바라면. 그렇지 않으면 귀하의 답변에 대한 명확한 설명이 필요할 것입니다. –