1. 메모리 누수란?
- 개인적으로 필자가 cpp를 처음 공부할 때 이해하기 어려운 개념중에 하나였다.
- 메모리가 샌다는거 자체가 무슨말인데?? 메모리가 액체야? 그래서 새면 어떻게 되는건데???
- 결론부터 말하면 메모리누수란 "프로그램이 동적으로 할당한 메모리를 반환하지 않고 계속해서 쌓이는 현상" 을 말한다.
- 직관적으로 설명하면 여러분들한테 "배낭" 이라는 메모리가 있다고 가정하자. (여러분은 집에서 출발한다!!!)
- 정적과 동적은 따로 글을 쓸 필요가 있지만 여기서 간단하게만 설명을 하면
- 정적으로 배낭에다 물건을 넣는 행위 == 여러분이 집에서 나올 때 필요할 것 같은거 미리 정해서 챙겨나오는 것
- 동적으로 배낭에다 물건을 넣는 행위 == 길을 걸으면서 그때 그때 상황에 맞춰 길에 있는거 주워다 배낭에다 넣는 것
- 으로 이해하면 좋을 것이다.
- 다시 상황으로 돌아와서 여러분이 길을 걷다가 초콜릿을 2개 주웠다고 가정해보자
- 이런! 여러분들의 가방 공간이 줄었다. 이제 여러분은 16칸 중 14칸만 사용이 가능하다.
- 하지만 배고파서 초콜릿을 먹는다면? 다시 여러분의 배낭은 16칸이 남아있으면 좋겠지만..
- 자원을 사용하고 (여기선 초콜릿을 먹고) 여러분의 공간이 제대로 돌아오지 않았다.
- 만약에 이런 상황에서 초콜릿을 3개 더 주워먹고 쓰레기가 남고 계속 반복된다면??
- 여러분의 배낭은 어느 순간 가득 차 더이상 무언가를 추가로 넣지 못하게 될 것이다.
- 즉 메모리 누수가 지속되면 점차적으로는 시스템의 자원이 부족해지고 성능 저하와 결국에는 프로그램의 강제종료(크래시) 발생의 원인이 될 수 있다.
2. 메모리 누수의 원인
- 이 정도 설명했으면 이제 코딩이나 시스템에서의 예를 들어 이해할 수 있을 것이다.
2-1. 객체의 생성과 소멸이 제대로 이루어지지 않는 경우
#include <iostream>
class Resource {
public:
Resource() {
std::cout << "Resource 생성" << std::endl;
}
~Resource() {
std::cout << "Resource 소멸" << std::endl;
}
};
void createObject() {
Resource* obj = new Resource(); // 객체 생성
// 객체의 사용 코드 작성
delete obj; // 객체 소멸
}
int main() {
createObject();
return 0;
}
- 만약 이 코드에서 delete obj를 하지 않는다면 createObject() 를 호출할 때 마다 메모리(정확히는 heap)에 계속 객체가 삭제되지 않고 쌓여서 메모리 누수가 발생한다.
- 1번 주제에 예시를 생각하면 "초콜릿 객체"를 생성하고 사용했으면 쓰레기를 delte 해야 하는데 하지 않아서 "초콜릿 객체"가 계속 배낭에 남아있는 상태이다.
2-2. 자원 해제를 잊거나, 해제 과정에서 오류가 생기는 경우
#include <iostream>
#include <fstream>
void writeFile() {
std::ofstream file("example.txt"); // 파일 생성
// 파일에 데이터를 작성하는 코드 작성
file.close(); // 파일 닫기
}
int main() {
writeFile();
return 0;
}
- 파일을 생성하기 위해 파일 객체 자원을 사용했으면 file.close()로 파일을 닫아줘야 한다.
2-3. 루프나 재귀를 사용할 때 할당이랑 해제가 비대칭인 경우(쌍이 서로 안맞는 경우)
#include <iostream>
void allocateMemory(int n) {
for (int i = 0; i < n; i++) {
int* ptr = new int(i); // 메모리 할당
// 할당된 메모리를 사용하는 코드 작성
delete ptr; // 메모리 해제
}
}
int main() {
allocateMemory(5);
return 0;
}
- 위 코드를 보면 allocateMemory라는 함수에서 for로 반복을 돌면서 동적으로 메모리를 할당하고 있는데,
- 그럼 메모리 사용이 끝나면 끝날 때 마다 동적으로 메모리를 해제해 줘야한다!
- 학교에서 실습할 때 이중 배열관련해서 메모리 해제 할 때 머리가 아팠던 기억이 난다.
- 특히 재귀나 반복문을 사용할 때 좀더 주의하도록 하자. 할당한 무언가는 사용후에 반드시 해제해야한다.
- 위 코드에서는 같은 반복문 안에서 delete ptr;로 반복마다 해제를 해주고 있다.
3. 요약
- 당시 교수님 말씀으로는 메모리 누수는 코드를 작성할 때 집중하지 않으면 나중에 찾기도 어려워서 성능 개선에 어려움이 있다고 한다.
- 여러분들의 실력이 높아지면 높아질 수록 큰 프로젝트에 참여하는 경우가 많아 질테니
- 동적으로 할당한 메모리는 명시적으로 해제하고 객체 생성, 소멸 등의 과정에서 실수하지 않도록 조심하자
- 그런데 정작 나부터 메모리 누수가 성능에 문제 생길 정도의 프로젝트를 해본적 없다.
- 정진하자!!
'CS > Terminology' 카테고리의 다른 글
IT용어 - 하드코딩&소프트코딩 (0) | 2023.07.08 |
---|---|
IT용어 - 린터(linter) (0) | 2023.07.08 |