2011-04-19 9 views
2

SrcFile이라는 엔티티 클래스가 있고 해당 열 중 하나가 있습니다.왜이 코드는 느리고 느리게 실행됩니까?

@NotNull 
@Lob 
private Byte[] data; 

SrcFile에는 Report 엔티티와 OneToOne 관계가 있습니다.

Report.java에서 :

@OneToOne 
private SrcFile srcFile; 

SrcFile 엔터티를 유지하면 멋지게 작동합니다.

srcFileHomeFacade.clearInstance(); 
SrcFile srcFile = srcFileHomeFacade.getInstance(); 
byte[] bArray = resource.getBytesForSource(); 
srcFile.setData(ReportFileResource.toObject(bArray)); 
System.out.println("````````````````srcFile data length: "+bArray.length); 
srcFileHomeFacade.persist(); 

Report을 지속하면 문제가 발생합니다.

report.setSrcFile(srcFile); 
reportHomeFacade.persist(); 

이 코드를 여러 번 실행하면 멋지지만 은 느려지고 느린 (심지어 GC 오버 헤드 오류가 발생 함)와 조사 시간 후이 report.setSrcFile(srcFile)가 문제.

어쨌든 보고서는 srcFile.data 같은 양의 참조를 좋아하지 않습니다 ...

원인을 확인하십시오?

만약 내가 report.setSrcFile 모든 좋은 작품 (단, 보고서 테이블의 SRCFILE_ID는 null이 될 것입니다하지만 그것은 단지 테스트를위한 것입니다). 데이터의 길이는 약 100.000입니다.

참고 : report을 유지하지 않고 srcFile 엔티티 만 유지하면 문제가 없습니다. 업데이트 :

"느리고 느리게 실행" 설명 :이 코드는 일부 pcl을 pdfs로 변환하기 위해 호출되므로 data에는 pcl의 소스가 들어 있으며 매번 다른 경우가 있습니다. 약 100 pcls를 변환하면 프로세스가 느려지고 느려지 며 VM에서는 MB 메모리가 많이 필요한이 바이트 [] 배열을 발견했습니다. 다시 말하지만 IO에 대해서는 문제가 아니지만 보고서 엔티티에 대한 setSrcFile에 대해 VisualVM에서도이를 나타냅니다.

+2

자바라고하기 때문에 : – ThiefMaster

+1

@ThiefMaster : 매우 도움이됩니다.) – weltraumpirat

+0

"여러 번 실행"이라고 할 때 다음과 같은 내용을 명심하십시오. 동일한 엔터티를 여러 번 유지합니까? 프로그램이 지속적이거나 데이터를 읽을 때만 느리게 실행됩니까? 데이터를 쓰는 동안 읽기 작업을 실행합니까? 동일한 보고서에 다른 파일을 설정합니까, 아니면 하나의 보고서에 대해 항상 동일한 srcFile입니까? CascadeTypes를 설정합니까? 게으른로드 나 열심히로드합니까? – weltraumpirat

답변

2

아직도 조금 확신이 들지 않지만 문제가 지속되고 엔티티 개체를 처리하는 방식과 관련이 있다고 생각됩니다. 일단 유지 된 엔티티를 제대로 폐기하면 GC는 시스템이 원활하게 실행됩니다. 특히 각 트랜잭션 후에 flush() 또는 commit()을 사용하면 메모리 사용량이 계속 증가하지 않아야합니다. 귀하의 경우에는 모든 엔티티가 더 이상 필요하지 않게 된 후에도 모든 엔티티가 메모리에 남아있는 것으로 보이므로 리소스가 해제되지 않은 몇 가지 이유가 있어야합니다.

임의의 for 루프를 사용하여 srcFiles 세트를 반복하고 그 안에 모든 persist() 호출이 직접 있습니까? 그렇다면 범위와 관련된 문제 일 수 있습니다. 루프의 내용을 새로운 메소드로 추출하여 각 반복 후에 모든 로컬 변수를 적절하게 해제하려고 할 수 있습니다.

CascadeType.PERSIST 또는 CascadeType.ALL을 설정하고 보고서에서 하나의 persist() 연산을 사용하여 두 개체를 모두 저장하면 작업을 향상시킬 수도 있습니다. FetchType.LAZY도 도움이 될 수 있습니다.

어떤 경우 : 데이터베이스에 저장하고 나중에 잊어 버리지 않고 프로그램에서 모든 항목을 메모리에서 직접 사용할 수있는 이유를 찾아보십시오.

+0

질문에 세부 사항이 부족하여 매우 그럴듯한 가능성이 있습니다. – vickirk

+0

자세한 답변을 주셔서 감사합니다. 이음새를 사용하고 있으며 트랜잭션 처리 및 구성 요소 릴리스를위한 모든 관리가 Seam에 의해 수행되도록 @Transactional로 유지하는 메소드에 주석을 달았습니다 ... CascadeType.PERSIST로 시도 할 것입니다. –

+0

굉장합니다. 그것은 CascadeType.PERSIST 및 FetchType.LAZY와 함께 작동합니다 ... 이것은 리포트를 지속 한 후에도 리포트가 메모리에 남아 있으면 srcFile이 그것에 의해 분리되지 않는다는 것을 의미합니까? 그렇다면 srcFile이 매우 거대한 것이기 때문에 모든 것보다 의미가 있습니다 .... –

0

BLOB에 대한 원시 JDBC 인터페이스가 까다로울 수 있으며 공급 업체 객체를 수동으로 close()해야한다는 사실을 기억합니다. 이 단계를 빠뜨리면 JDBC 드라이버 (예 : JVM 메모리)에 BLOB가 누적되어 JVM이 결국 OOM으로 바뀝니다.

저장 후 BLOB를 닫기 위해 수행 할 공급 업체별 속성이나 단계가 필요한지 궁금합니다.

관련 문제