2009-12-03 3 views
0

이전에이 질문을했지만 필자는 몇 가지 사항을 다시 말하고 명확히하고 확장하려고합니다. AffineTransform을 사용하여 BufferedImage를 변환하는 코드 조각이 있습니다.AffineTransformOp 속도/메모리 질문

op = new AffineTransformOp(atx, interactive ? interpolationInteractive : interpolationNormal); 
displayImage = op.filter(displayImage, null); 

이 코드는 정상적으로 작동하지만 메모리가 누적됩니다. 특히이 코드 조각을 호출 할 때마다 더 많은 메모리가 저장됩니다. 나는 필터의 다른 형태도 시도했다.

op = new AffineTransformOp(atx, interactive ? interpolationInteractive : interpolationNormal); 
displayImage2 = op.createCompatibleDestImage(displayImage, displayImage.getColorModel()); 
op.filter(displayImage, displayImage2); 

그러나 이것은 첫 번째 버전보다 훨씬 느립니다. 두 번째 메모리 사용량으로 첫 번째 버전의 속도를 원합니다.

  1. 첫 번째 버전 이후에는 어떻게 정리할 수 있습니까? 특히, 중간 BufferedImages는 어디에 저장되며 어떻게 삭제할 수 있습니까?
  2. 두 번째 버전이 첫 번째 버전보다 느린 이유는 무엇입니까? 속도를 높이려면 어떻게해야합니까?

도움 주셔서 감사합니다.

+1

실제로 OutOfMemoryErrors를 받고 있습니까? 그렇지 않다면 GC가 실제 메모리 누수가 아닌 객체를 수집 할 때의 문제 일뿐입니다. –

답변

0

당신은 displayImage와 (과) ColorModel을 어떻게 사용하고 있습니까?

IndexColorModel 인 경우 많은 설명이 될 수 있습니다.

첫 코드 조각은 DirectColorModel을 사용하여 BufferedImage을 반환합니다. 픽셀 당 4 바이트 대 보통 인덱스 이미지의 경우 픽셀 당 1 바이트가 필요합니다. 1 : 4로 확장하면 메모리 부족 상태가 될 수 있습니다.

두 번째 코드 단편은 BufferedImage을 소스와 동일한 모델로 만듭니다. 이것이 IndexColorModel이고 보간이 NEAREST_NEIGHBOR이 아닌 경우 filter() 호출은 DirectColorModel의 임시 BufferedImage을 생성합니다. 그것을 필터 작업의 대상으로 사용하고 임시 버퍼를 재 양자화하여 displayImage2에 그립니다. 그래서, bitblits의 두 배.

단 하나의 변환을 수행하는 경우 두 번째 형식으로 이동한다고 말하고 싶습니다.

여러 작업을 수행하는 경우 DirectColorModel과 함께 BufferedImage 쌍을 할당하십시오. 당신의 가장 큰 이미지를 담을만큼 충분히 큽니다. 원본 이미지를 그 중 하나에 그려 넣고 그 사이에서 필터를 앞뒤로 수행하십시오. 그런 다음 끝나면 ColorConvertOp을 사용하여 색인 된 이미지로 다시 재협상하십시오. 그렇게하면 각 필터 호출 대신 한 번만 색상을 변환하면됩니다.

+0

두 번째 제안을 시도 할 것입니다. 먼저 ColorConvertOp를 사용하여 직접 색상 모델에서 인덱스 색상 모델로 변환하는 방법을 알려주시겠습니까? – Jon

+1

ColorConvertOp는 AffineTransformOp와 같이 작동하지만'filter (src, dst)'를 호출하여 원하는 색상 모델의 기존'BufferedImage'로'dst'를 전달해야합니다. –

+0

좋아,하지만 어떻게 ColorConvertOp에서 생성자를 사용합니까. 나는 다음을했다. ColorModel indexColorModel = displayImage.getColorModel(); displayImage = op.filter (displayImage, null); ColorConvertOp colorOp = new ColorConvertOp (indexColorModel.getColorSpace(), displayImage.getColorModel(). getColorSpace(), null); displayImage = colorOp.filter (displayImage, null); 그리고 이것을 실행하면 필터 라인에 멈추어 서 결코 돌아 오지 않습니다. – Jon

0

당신이 OutOfMemoryErrors를 얻지 않는 한 코멘트에 동의합니다. 그러면 이것은 정상적인 것이며, GC는 적합하다고 판단 될 때마다 이미지를 수집합니다. 여기에 가끔 어리석은 시험을 할 때가있다 : 주요 함수의 루프에 넣고 프로파일 러에서 메모리 사용을 관찰한다. (지그재그 같은 패턴이나 뭔가를 만들어야한다.) 그러나 항상 완료 할 수있는 것은 아니다. 성공적으로

+0

메모리 부족 문제가 있습니다. 메모리가 너무 높을 때 System.finalization 및 System.gc를 실행하여 속도를 늦출 수있었습니다 (메모리 관리를 추적하는 스레드가 있음). – Jon

+0

지금 작업하고 있다면 괜찮습니다. 저에게 메모리 관리 추적 스레드가 있다고해도 - 마치 Java의 메모리 관리를 다시 작성하려고 시도하는 것처럼 어쨌든 좋지는 않을 것입니다. 어리석은 소리가 나지만 힙에 충분한 공간을 할당하지 않습니까? 이미지 트랜스 폼을 많이 사용하고 있었을 때 512 또는 1024를 할당해야했습니다. 또한 JVM에서 메모리 및 GC와 관련된 많은 매개 변수를 설정할 수 있습니다. http://java.sun.com/docs/hotspot/gc5.0/gc_tuning_5.html –