7. • 본적인 골자는 자주 사용하는 데이터만 메모리에 올리고 자주
사용되지 않는 건 사용할 때만 잠깐 올린다.
• 메모리 최적화 이득이 큰 데이터라면 내려버리고, 올려야 할 조
건을 강화한다. 최대한 티가 나지 않도록
8. 최적화된 String 사용
MSVC 1926 x64 기준 std::string 크기는 32 Byte
실제 구현을 보면 문자열 포인터 외, 사이즈 등을 위한 데이터가 추가적으로 들어가있음
size_type _Mysize; // current length of string
size_type _Myres; // current storage reserved for string
때문에 메모리 사용량을 줄이려한다면
size나 length 조작이 필요없는 문자열 데이터에 한해 최적화 된 String을 사용
9. 최소 컨테이너 사용
컨테이너에 따라 원소 추가 때마다 추가적으로 요구되는 메모리가 있음
List(+16 Byte)
•왼쪽 자식 노드를 가리키는 포인터
•오른쪽 자식 노드를 가리키는 포인터
Vector
Capacity에 따른 리사이즈
Set(+32 Byte)
•왼쪽 자식 노드를 가리키는 포인터
•오른쪽 자식 노드를 가리키는 포인터
•정렬 순서상 이전 노드를 가리키는 포인터
•정렬 순서상 다음 노드를 가리키는 포인터
Map(+40 Byte)
•Key
•왼쪽 자식 노드를 가리키는 포인터
•오른쪽 자식 노드를 가리키는 포인터
•정렬 순서상 이전 노드를 가리키는 포인터
•정렬 순서상 다음 노드를 가리키는 포인터
Unordered_Map(+16 Byte)
•Key
•Hash
가급적 vector를 사용하고
vector를 기반으로한 커스텀 컨테이너 사용
11. class B
{
bool a;
bool b;
int64_t c;
bool d;
};
A B C C C C C C C C D
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
8 Byte 8 Byte
C를 가져오려면?
12. A B C C C C C C C C D
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
8 Byte
Padding Padding
가장 큰 멤버 크기를 기준으로
(MSVC 기본 패킹 단위 8Byte / 32bit/64bit 동일)
각 데이터 사이에 패딩을 집어넣는다
기계한테만…
13. A B C C C C C C C C D
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
Padding Padding
24 Byte 중 절반이 넘게 질소 포장….
14. C C C C C C C C A B D
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
A B C C C C C C C C D
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
Padding
Padding
class B
{
bool a;
bool b;
int64_t c;
bool d;
};
class B
{
int64_t c;
bool a;
bool b;
bool d;
};
8 Byte
1 Byte
1 Byte
1 Byte
Padding
24 Byte -> 16 Byte
무려 1/3이 감소
만약 이러한 데이터가 300MB가 있었다면 100MB 가량 감소하는 셈
15. Memory Alignment 규칙
• 멤버 변수중 가장 큰 사이즈를 사용. (기본 alignment)
#pragma pack (push, 1) // Total 11
Byte
class foo
{
bool a;
bool b;
int64_t c;
bool d;
};
#pragma pack (pop)
• 멤버 변수 중 가장 큰 사이즈와 프로젝트 세팅에서 지정한 수치 중
작은 녀석을 사용 (선택적 alignment)
struct __declspec(align(2)) Foo
{
char a;
int b;
};
• 위 모든 규칙을 무시하고 (지정 되었다 하더라도
overwrite 한다는 의미) 사용자가 지정한 사이즈를 사
용 (절대적 alignment)
17. • 상속을 사용하지 않는 클래스의 경우 virtual 키워드를 제거한다
• 파생 클래스에서 사용할 변수는 부모 클래스에 선언하지 않는다
• 메모리 누수를 잡자
• Stl 컨테이너 사용시 미리 사이즈를 알 수 있을 때는 reserve 사용, resiz하더라도 반드시 shirink_to_fit 적
용
• 0이라면 사용하지 않으니 메모리에서 내린다, 예를 들어 볼륨이 0일 경우 소리를 듣지 않는 다는
• 소리이니, 오디오 리소스를 내려버리자 ^^
• 비트 플래그 적극 활용