이미지 파일을 파일 시스템으로 서비스에 업로드할때,
화면이 하얗게 브라우저 크래시가 되는 문제가 있었다.
이때 1개의 사이즈가 40mb짜리 bmp확장자 사진 60장을 사용하여,
동시에 많은 메모리가 로드 되도록 하여 해당 문제원인을 발견하였다.
JavaScript에서 파일을 업로드하고 처리할 때 힙 메모리가 사용한다.
특히 이미지 파일의 경우 다음과 같은 과정에서 메모리를 사용한다:
- 파일 로딩
- 파일을 FileReader나 URL.createObjectURL()로 읽을 때
- 이미지 데이터를 JavaScript 객체로 변환할 때
JavaScript는 브라우저나 Node.js 환경에서 사용할 수 있는 힙 메모리에 제한이 있는데, 특히 브라우저에서는 이 제한이 더 엄격하다.
해당 메모리에 대한 제한때문에 문제가 생긴것으로 파악하였다.
그래서 배치 처리 방식으로 해결하기로 결정하였다.
한 번에 처리하는 이미지 수를 제한하여 메모리 사용량을 안정적으로 유지하고, 이미지 크기에 따라 자동으로 배치 크기를 조절해주면 될 것이라 생각했다.
배치처리를 하는것과 안하는것에 차이가 나는 이유는
한 시점에 사용하는 최대 메모리양(피크) 과 가비지 컬렉션 기회가 생기기 때문이다.
- 한번에 처리: GC가 동작할 기회가 적음
- 배치 처리: 각 배치 사이에 GC가 동작할 수 있는 기회가 생김
또한 브라우저 동작하는데 더 안정적이다.
- 한번에 처리: 브라우저가 메모리 한계에 도달하면 크래시 발생 가능
- 배치 처리: 적절한 메모리 관리로 안정적 동작
따라서 총 처리하는 데이터의 양은 같지만, 한 시점에 사용하는 최대 메모리양(피크)을 제어할 수 있고, 중간에 GC가 동작할 기회를 제공하여 더 안정적인 메모리 관리가 가능해진다.
// 모든 파일을 한번에 처리
const processAllDocuments = async (files) => {
// 100개의 문서를 동시에 메모리에 로드
const allDocs = await convertDocsToPreview(files) // 🚨 최대 메모리 사용량 발생
return allDocs
}
const processDocumentsInBatches = async (files) => {
const allDocs = []
// 20개씩 처리
for (let i = 0; i < files.length; i += 20) {
const batch = files.slice(i, i + 20)
const batchDocs = await convertDocsToPreview(batch) // ✅ 메모리 사용량 제한
allDocs.push(...batchDocs)
// 이전 배치의 임시 데이터는 GC에 의해 정리될 수 있음
}
return allDocs
}
'웹' 카테고리의 다른 글
Indexed DB 란??? [Chrome Extension을 개발하며] (0) | 2025.01.09 |
---|---|
Enum을 사용하면 안되는 이유 (0) | 2024.09.02 |
Github Action build error 해결 (0) | 2024.07.24 |
Next js Lottie 사용할때 Document is not defined Build 에러 (0) | 2024.06.26 |
Mock Service Worker (0) | 2024.05.23 |