자바, Go, 파이썬 등 언어는 가비지 컬렉터를 쓴다. 이거 쓰는 언어는 사용이 끝난 객체를 힙 메모리에서 바로 삭제 않고 정해진 규칙에 따라 사용하지 않는 메모리를 찾아 반환한다.
가비지 컬렉터는 개발자가 메모리를 직접 관리해야하는 부담을 줄여준다. 코드로 메모리 관리를 못해서 보안 이슈를 줄여주는 장점도 있다. 하지만 응답 시간에 영향을 줄 수 있다. 가비지 컬렉터가 실행되는 동안 애플리케이션의 실행이 일시 중단되는데 이를 모든 실행이 멈춤다 하여 ‘Stop The World’라 표현하기도 한다.
메모리를 많이 쓰고 생성된 객체 많을수록 사용하지 않는 객체 찾는데 오래 걸린다. GC 알고리즘와 메모리 사용패턴에 따라 차이가 있지만 사용하는 메모리와 객체 많을 수록 GC 실행 시간은 길어진다.
예를 들어 JVM 에 할당된 최대 힙 크기를 4G → 2G로 하면 GC가 탐지하고 제거해야할 객체 개수가 줄어든다. 그만큼 GC 수행시간도 짧아진다. 물론 애플리케이션 요구사항에 따라 조절해야되는 거고.
한 방에 대량 객체 생성도 주의하자. 대량으로 객체 생성 방지하려면 조회 범위를 제한하던가 하면된다. 최대 3개월치만 보게한다던가.
파일 다운로드 같은 기능을 구현할 때는 스트림을 활용한다. 다음 자바 코드처럼 파일 데이터를 한꺼번에 로딩해서 응답하는 방식은 피해야한다. 파일 크기와 동시 사용자 수에 따라 메모리 사용량이 급등할수 있기 때문이다. 이 코드는 30MB 크기의 파일을 100명이 동시에 다운로드하면 약 3GB의 메모리가 필요하게 된다.
byte[] bytes = Files.readAllBytes(Path.of("path"));
out.write(bytes);
//파일을 한방에 메모리에 로딩스트림을 쓰면 파일 처리 과정에서 필요한 메모리 크기 줄일 수 있다. 다음은 스트림을 이용하도록 변환한 코드.
InputStream is = FIles.newInputStream(Path.fo("path"));
byte[] buffer = new byte[8192]; // 8KB
int read;
while((read = is.read(buffer, 0, 8192)) >= 0){
out.write(buffer, 0, read);
}이 코드는 파일을 한 번에 읽지 않고 8KB 씩 끊어 읽는다. 동시에 100명이 다운로드 요청해도 필요 메모리는 800KB에 불과하다.