코딩일상

[Node.js] 메모리 누수 총 정리(1) 본문

개발 공부/Node.js

[Node.js] 메모리 누수 총 정리(1)

solutionMan 2024. 3. 12. 17:34
반응형

 

1.메모리 누수는 무엇인가?


메모리 누수는 부주의 또는 일부 프로그램 오류로 인해

더 사용되지 않는 메모리를 해제하지 못하는 것이다.

 

간단히, 어떤 변수가 100M의 메모리를 점유한다고 할 때,

이 변수가 사용되지 않더라도 수동 또는 자동으로 해제되지 않아 계속 메모리를

점유하는 것을 말한다

2.왜 발생하는가?


사용되지 않는다고 판단되는 변수들을 담은 힙 메모리에서 GC를 해주어야 하는데

어떠한 이유들로 GC가 되지 않기 때문에

 

2-1 GC 가비지 컬렉션이란?

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <title>메모리 사용량 확인하기</title>
</head>
<body>
    <button id="create">대량의 데이터 생성</button>
    <button id="release">데이터 해제 및 메모리 사용량 확인</button>

    <script>
        let hugeData = null;

        document.getElementById('create').addEventListener('click', function() {
            hugeData = new Array(1000000).fill('NodeJS Copilot');
            console.log('대량의 데이터가 생성되었습니다.');
            logMemoryUsage();
        });

        document.getElementById('release').addEventListener('click', function() {
            hugeData = null;
            console.log('데이터가 해제되었습니다. 가비지 컬렉션을 기다리세요.');
            // 가비지 컬렉션 후 메모리 사용량을 확인하기 위해,
            // 비동기로 일정 시간 후 메모리 사용량을 로그합니다.
            setTimeout(logMemoryUsage, 1000); // 1초 후 메모리 사용량 로그
        });

        function logMemoryUsage() {
            if (performance.memory) {
                console.log(`JS 힙 사용량: ${(performance.memory.usedJSHeapSize / 1024 / 1024).toFixed(2)} MB`);
            } else {
                console.log('이 브라우저는 performance.memory를 지원하지 않습니다.');
            }
        }
    </script>
</body>
</html>

 

3.어떤 경우 발생하는가?

메모리 누수 예제들 그래서 어떤 상황들에서 메모리 누수가 발생이 될까? 다음은 공통적인 사례들이다.

1.클로저의 잘못된 사용

2.의도치않게 생성된 전역 변수

3.분리된 DOM 노드콘솔 출력

5.해제하지 않은 타이머

1. 잘못된 클로저의 사용

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <title>잘못된 클로저 사용 예제</title>
</head>
<body>
    <script>
        function createClosure() {
            let hugeData = new Array(1000000).fill('*');
            return function() {
                console.log("클로저 내부에서 참조되는 데이터가 있습니다.");
            };
        }
        let closure = createClosure(); // hugeData를 참조하는 클로저 생성
        // 이론적으로는 여기서 hugeData에 대한 참조를 해제할 수 있지만,
        // 클로저가 hugeData를 참조하고 있어서 메모리 누수가 발생합니다.
    </script>
</body>
</html>

 

클로저란??

function createCounter() {
    let count = 0; // `createCounter`의 지역 변수
    return function counter() {
        count = count + 1; // 외부 함수의 변수를 업데이트
        console.log(count);
    };
}

const myCounter = createCounter(); // `createCounter` 실행, `counter` 함수 반환

myCounter(); // 1 출력
myCounter(); // 2 출력
myCounter(); // 3 출력

// `myCounter`는 `createCounter`의 `count` 변수를 기억합니다.
// 이것이 바로 클로저의 힘입니다!

 

2.의도치 않은 전역 변수 생성

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <title>의도치 않은 전역 변수 생성 예제</title>
</head>
<body>
    <script>
        function createGlobalVariable() {
            unintentionalGlobal = "이 변수는 전역 변수로 생성됩니다."; // var, let, const 키워드 없이 선언
        }
        createGlobalVariable();
        console.log(window.unintentionalGlobal); // 전역 변수로 접근 가능
    </script>
</body>
</html>

종료되지 않은 타이머

<script>
    let timerId = setInterval(() => {
        console.log("타이머가 작동중입니다."); // 이 타이머는 페이지에서 명시적으로 정지되지 않는 한 계속 실행됩니다.
    }, 1000);

    // clearInterval(timerId); // 타이머를 정지시키지 않으면, 페이지가 닫혀도 내부적으로 계속 실행되어 메모리 누수가 발생할 수 있습니다.
</script>

 

4.어떻게 해결 해야하나

 

메모리 누수가 나는곳을 파악을 해서 

그부분이 메모리를 계속 차지 하지 않도록 처리를 해야한다.

4-1) 모니터링

2부에서 계속

 

Nodejs - 메모리 누수 확인

1. 개요 2. 메모리 누수란? 3. 메모리 누수 확인 4. 노드 크롬 디버거 5. 누수 발생 확인 수많은 글들이 노드의 메모리 누수에 대한 글들을 설명하고 해결방법, 대안을 포스팅했지만 정말 겉만 번지

ajh322.tistory.com

 

 

heap out of memory 에러 해결과 메모리 누수 검사(node.js)

해당 글은 SOPT 30기 활동 중 SOPT 기술 블로그에 제가 작성했던 글입니다.

choo.oopy.io

 

4-2) 해결법

2부에서 계속

 

 


참고

 

당신이 모르는 자바스크립트의 메모리 누수의 비밀

크롬 개발자도구로 하는 디버깅과 해결책을 찾아서!

ui.toast.com

 

반응형
Comments