반응형

해당 에러는 개발 시 메모리를 많이 사용하는 부분이 생성되어

코드 중 어느 부분인가 잘못되면 메모리가 사용 되게 되었다.

오늘은 잘못 짠 내 코드를 보면서 개선해보겠다.

// file : File 변수
// s3Client :s3 uploader

byte[] bytes = IOUtils.toByteArray(file.getInputStream());
    	
ObjectMetadata objMeta = new ObjectMetadata();
objMeta.setContentLength(bytes.length);
ByteArrayInputStream byteArrayIs = new ByteArrayInputStream(bytes);
s3Client.putObject(new PutObjectRequest(filePath, fileName, byteArrayIs, objMeta)
        .withCannedAcl(CannedAccessControlList.PublicRead));
s3Client.getUrl(filePath, fileName).toString();

 

아직도 스트림에 대해서 제대로 이해를 하지 못하는 수준의 코드이다.

 

 

대략적으로 설명을 하자면

S3 Uploader에서 Metadata 에 length를 계산하기 위해 IOUtils.toByteArray 으로 바이트로 변환하여

byte[] 을 .length로 출력한다.

이후 ByteArrayInputStream 으로 다시 변환하여 S3에 업로드 변수에 넣는다.

이렇게 설명할 수 있다.

 

보다 보니 반복되는 부분이 보이는것 같다. InpustStream이 두번 생성되는 부분이 있다.

코드 첫라인인 1번째 라인과 5번 라인에서 반복되는 구문이 보인다. 이렇게 사용하게되면 물론 반복에도 문제가 있지만

해당 서비스는 용량이 큰 파일을 upload하기때문에 메모리에 큰 부하가 오게된다.

개선하기 위해 아레와 같이 반복되는 부분을 제거하였다.

// file : File 변수
// s3Client :s3 uploader
    	
ObjectMetadata objMeta = new ObjectMetadata();
objMeta.setContentLength(bytes.length);
s3Client.putObject(new PutObjectRequest(filePath, fileName, file.getInputStream(), objMeta)
        .withCannedAcl(CannedAccessControlList.PublicRead));
s3Client.getUrl(filePath, fileName).toString();

 

 

반복 구문

 

byte[] bytes = IOUtils.toByteArray(file.getInputStream());

ByteArrayInputStream byteArrayIs = new ByteArrayInputStream(bytes);

OutputStream으로 만들고, InputStream으로 만드는 두 부분을 제거하였다.

반복되는 부분을 제거하고 메모리 모니터링을 진행한 결과

현저히 메모리 사용량이 줄어들었다. 엉뚱한곳을 바라보고 메모리 수정을 하였으나

Java heap memory 에러에서는 몇번째 라인에서 에러가 나는지 보여주고있었다.

꼭 에러로그에 기반한 오류수정을 우선적으로 하길.

+ Recent posts