Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
SlideShare a Scribd company logo

1

Memory & Object Pooling
NHN NEXT
๋‚จํ˜„์šฑ

2

Windows LFH
์žฆ์€ ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น / ํ•ด์ œ์˜ ๋ฐ˜๋ณต์‹œ ํž™์— ๋‚จ์€ ๋ฉ”๋ชจ๋ฆฌ์˜ ์–‘์ด ์ถฉ๋ถ„ํ•จ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  ๋” ์ด์ƒ ๋ฉ”๋ชจ๋ฆฌ์˜
ํ• ๋‹น์„ ์ง„ํ–‰ํ•  ์ˆ˜ ์—†๋Š” ์ƒํ™ฉ์ด ์ƒ๊ธด๋‹ค. ์ด๋ฅผ Heap fragmentation์ด๋ผ๊ณ  ํ•˜๋Š”๋ฐ, LFH๋Š” ์ด ํ˜„์ƒ
์„ ์ค„์ด๊ธฐ ์œ„ํ•ด ๊ณ ์•ˆ๋œ ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น ์ •์ฑ…์ด๋‹ค.
Heap - ๋นจ๊ฐ• : ํ• ๋‹น๋จ, ํฐ์ƒ‰ : ํ• ๋‹น ์•ˆ ๋จ
์ด ์ •๋„ ํฌ๊ธฐ ํ• ๋‹นํ•˜๋ ค๊ณ  ํ•  ๋•Œ ํž™์— ์—ฌ์œ  ๊ณต๊ฐ„์ด ์ถฉ๋ถ„ํžˆ ๋‚จ์•„ ์žˆ์Œ์—๋„ ๋ถˆ
๊ตฌํ•˜๊ณ  ๋ถ€๋ถ„๋ถ€๋ถ„ ์ž˜๋ ค์žˆ์–ด ํ• ๋‹น์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค!! -> fragmentation

3

Windows LFH
LFH๋Š” ์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด 128๊ฐœ์˜ ์„œ๋กœ ๋‹ค๋ฅธ ํฌ๊ธฐ์˜ bucket์„ ๋ฏธ๋ฆฌ ๊ตฌ์„ฑํ•œ ํ›„, ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น ์š”์ฒญ
์ด ์ผ์–ด๋‚ฌ์„ ๋•Œ ํ•ด๋‹น ์‚ฌ์ด์ฆˆ๋ฅผ ํฌํ•จํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ€์žฅ ์ž‘์€ ํฌ๊ธฐ์˜ bucket์„ ์„ ํƒํ•ด ๊ฑฐ๊ธฐ ํ• ๋‹นํ•œ๋‹ค.
Buckets Granularity(์ฆ๊ฐ€ํญ) Range(์‚ฌ์ด์ฆˆ ๋ฒ”์œ„)
1 - 32 8 1-256
33 - 48 16 257-512
49 - 64 32 513-1024
65 - 80 64 1025-2048
81 - 96 128 2049-4096
97 - 112 256 4097-8192
113 - 128 512 8193-16384
๋”ฐ๋ผ์„œ ๋ฒ„ํ‚ท ์‚ฌ์ด์ฆˆ๋Š” ์ฐจ๋ก€๋Œ€๋กœ 1๋ฒˆ = 8Bytes, 2๋ฒˆ = 16Bytes, 3๋ฒˆ = 24Bytes, 4๋ฒˆ = 32Bytes...
ํฌ๊ธฐ๊ฐ€ ๋œ๋‹ค. ๋งŒ์•ฝ 21Byte ํฌ๊ธฐ์˜ ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น ์š”์ฒญ์ด ๋“ค์–ด์˜จ๋‹ค๋ฉด ํ•ด๋‹น ํฌ๊ธฐ๋ฅผ ์ˆ˜์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ€์žฅ
์ž‘์€ ํฌ๊ธฐ์˜ ๋ฒ„ํ‚ท์€ 24Bytes ์‚ฌ์ด์ฆˆ์˜ 3๋ฒˆ ๋ฒ„ํ‚ท์ด๋ฏ€๋กœ 3๋ฒˆ ๋ฒ„ํ‚ท์ด ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น์— ์“ฐ์ธ๋‹ค.

4

Windows LFH
LFH๋ฅผ ์“ฐ๊ธฐ ์œ„ํ•œ ์ „์ œ ์กฐ๊ฑด์ด ์žˆ๋‹ค(์•„๋ž˜ ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜์ง€ ์•Š์œผ๋ฉด LFH๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค).
โ€ข	ํ• ๋‹น ํฌ๊ธฐ๋Š” 16kb๋ณด๋‹ค ์ž‘์•„์•ผํ•œ๋‹ค. ์•ž์˜ ํ‘œ์—์„œ๋„ ๋ณผ ์ˆ˜ ์žˆ์ง€๋งŒ 16kb๋ณด๋‹ค ํฐ ํฌ๊ธฐ์˜ bucket์€
์—†๊ธฐ ๋•Œ๋ฌธ์— ์–ด์ฐŒ๋ณด๋ฉด ๋‹น์—ฐํ•˜๋‹ค.
โ€ข	HEAP_NO_SERIALIZE(๊ผญ ์ˆœ์ฐจ์ ์œผ๋กœ ์ ‘๊ทผํ•˜์ง€ ์•Š์•„๋„ ๋˜๋ฉฐ ์ ‘๊ทผ์‹œ lock์ด ๊ฑธ๋ฆฌ์ง€ ์•Š๋Š” heap)
๋กœ ์ƒ์„ฑ๋œ heap์—๋Š” ์‚ฌ์šฉ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค.
โ€ข	๊ณ ์ • ํฌ๊ธฐ(Fixed Size)๋กœ ์ƒ์„ฑ๋œ heap์—๋Š” ์ ์šฉ์ด ๋˜์ง€ ์•Š๋Š”๋‹ค.
โ€ข	๋””๋ฒ„๊น… ํˆด์—์„œ๋Š” LFH๊ฐ€ ๋™์ž‘ํ•˜์ง€ ์•Š๋Š”๋‹ค.
๊ทธ๋ฆฌ๊ณ  ํ•œ ๋ฒˆ LFH๋ฅผ ์ ์šฉ์‹œํ‚ค๋ฉด ์ด๊ฑธ ๋˜๋Œ๋ฆฌ๋Š” ๊ฒƒ์€ ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค.
LFH๋Š” 16KB ๋ฏธ๋งŒ์˜ ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น์ด ๋นˆ๋ฒˆํ•˜๊ฒŒ ์ผ์–ด๋‚˜๋Š” ๋ฉ€ํ‹ฐ ์Šค๋ ˆ๋“œ ํ™˜๊ฒฝ์—์„œ ๋›ฐ์–ด๋‚œ ์„ฑ๋Šฅ์„ ๋ณด์ธ
๋‹ค๊ณ  ํ•œ๋‹ค.

5

Windows LFH
์‚ฌ์šฉ๋ฒ•. ๋งค์šฐ ๊ฐ„๋‹จํ•˜๋‹ค. windows Vista ์ด์ƒ๋ถ€ํ„ฐ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ LFH๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๊ณ  ํ•œ๋‹ค.
ULONG heapFragValue = 2;
HeapSetInformation(GetProcessHeap(), //default heap์˜ ํ•ธ๋“ค์„ ๋ฐ›์•„์˜ด
			HeapCompatibilityInformation,
			&HeapFragValue,
			sizeof(HeapFragValue));
์œ„ ์ฝ”๋“œ๋ฅผ ์ˆ˜ํ–‰ํ•˜๋ฉด Default Heap์ด LFH๋กœ ๋ฐ”๋€๋‹ค. ์ด์ œ ๊ทธ๋ƒฅ new delete ์“ฐ๋ฉด ์ž๋™์œผ๋กœ LFH์˜
์ •์ฑ…์— ๋”ฐ๋ผ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ํ• ๋‹น๋œ๋‹ค.

6

Windows LFH
Windows Internals์˜ LFH์— ๋Œ€ํ•œ ์„ค๋ช… - ๋ฉ€ํ‹ฐ ์Šค๋ ˆ๋“œ์—์„œ ์ž˜ ๋™์ž‘ํ•˜๋Š” ์ด์œ ?
... The LFH addresses these issues(* fragmentation) by using the core heap manager and look-aside
lists. The Windows heap manager implements an automatic tuning algorithm that can enable the LFH
by default under certain conditions, such as lock contention or the presence of popular size allocations
that have shown better performance with the LFH enabled. For large heaps, a significant percentage of
allocations is frequently grouped in a relatively small number of buckets of certain sizes. The allocation
strategy used by LFH is to optimize the usage for these patterns by efficiently handling same-size blocks.
To address scalability, the LFH expands the frequently accessed internal structures to a number of
slots that is two times larger than the current number of processors on the machine. The assignment
of threads to these slots is done by an LFH component called the affinity manager. Initially, the LFH
starts using the first slot for heap allocations; however, if a contention is detected when accessing some
internal data, the LFH switches the current thread to use a different slot. Further contentions will spread
threads on more slots. These slots are controlled for each size bucket to improve locality and minimize
the overall memory consumption. ...
๋ผ๊ณ  ์„ค๋ช…ํ•˜๊ณ  ์žˆ์œผ๋‚˜ ์†”์งํžˆ ๋ฌด์Šจ ์†Œ๋ฆฌ์ธ์ง€ ์ •ํ™•ํžˆ ์ดํ•ด๋ฅผ ๋ชปํ•˜๊ฒ ๋‹ค. ์ž์ฃผ ์ ‘๊ทผ๋˜๋Š” ๋‚ด๋ถ€ ๊ตฌ์กฐ์ฒด์—
๋Œ€ํ•ด ํ•ด๋‹น ์Šฌ๋กฏ์— ๋Œ€ํ•œ ์Šค๋ ˆ๋“œ์˜ ๋Œ€์ž…(assignment)์—์„œ lock contention์ด ์ผ์–ด๋‚˜๋ฉด ๋‹ค๋ฅธ
์Šฌ๋กฏ์„ ์“ฐ๊ฒŒ ํ•ด์ฃผ๋ฉฐ, ์Šฌ๋กฏ๋“ค์€ ๊ฐ ์‚ฌ์ด์ฆˆ์˜ ๋ฒ„ํ‚ท์— ์˜ํ•ด ์ œ์–ด๋œ๋‹ค๊ณ  ํ•œ๋‹ค(์ง€์—ญ์„ฑ๊ณผ ๋ฉ”๋ชจ๋ฆฌ ์†Œ๋ชจ
์ตœ์ ํ™”๋ฅผ ์œ„ํ•ด). ๊ทผ๋ฐ ์Šฌ๋กฏ์ด๋ž‘ ๋‚ด๋ถ€ ๊ตฌ์กฐ์ฒด, affinity manager๊ฐ€ ๋‹น์ตœ ์ •ํ™•ํžˆ ๋ญ”์ง€...

7

Windows LFH
์•„๋ฌดํŠผ LFH ์„ฑ๋Šฅ์€ ๊ต‰์žฅํžˆ ์ข‹๋‹ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค. (๊ตฌ์Šน๋ชจ ๊ต์ˆ˜๋‹˜ ์˜คํ”ผ์…œ)

8

tcmalloc / jemalloc
tcmalloc์€ ์ด๋ฆ„๋ถ€ํ„ฐ thread cache malloc์œผ๋กœ, ๊ฐ ์Šค๋ ˆ๋“œ๋ณ„ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ์ž์™€ ์ค‘์•™ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ
์ž๋ฅผ ๊ตฌ๋ถ„ํ•˜์—ฌ ๊ด€๋ฆฌํ•œ๋‹ค. ์ž‘์€ ํฌ๊ธฐ(32kb)์˜ ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น์€ ์Šค๋ ˆ๋“œ๋ณ„ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ์ž์—์„œ ํ• ๋‹นํ•˜
๊ณ , ๊ทธ๋ณด๋‹ค ํฐ ํฌ๊ธฐ์˜ ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น์€ ์ค‘์•™ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ์ž๋กœ๋ถ€ํ„ฐ ๋ฐ›์•„์˜ค๋„๋ก ๋งŒ๋“ค์–ด์„œ ์ž‘์€ ๋ฉ”๋ชจ๋ฆฌ์˜
ํ• ๋‹น์ด ์žฆ๊ฒŒ ์ผ์–ด๋‚˜๋Š” ์ƒํ™ฉ์—์„œ๋Š” heap์˜ lock ๋•Œ๋ฌธ์— ๋ฐœ์ƒํ•˜๋Š” ์„ฑ๋Šฅ ์ €ํ•˜๊ฐ€ ์—†์–ด์„œ ์ข‹์€ ํšจ์œจ์„
๋ณด์ธ๋‹ค.
jemalloc์€ ํฌ๊ฒŒ Arena์™€ Thread cache๋ผ๋Š” ๋‘ ๊ฐœ์˜ ํ•ต์‹ฌ ๊ตฌ์กฐ๋กœ ์ด๋ฃจ์–ด์ ธ ์žˆ๋‹ค. Arena๋Š” ๋ฉ”๋ชจ
๋ฆฌ๋ฅผ ์ž‘์€ ๋ฉ์–ด๋ฆฌ๋กœ ์ž˜๋ผ ๊ฐ ์Šค๋ ˆ๋“œ์—๊ฒŒ ๋‚˜๋ˆ„์–ด ์ค€ ์˜์—ญ์ด๋‹ค. ์ฆ‰ ์ „์ฒด ํž™์—์„œ ๊ฐ๊ฐ์˜ ์Šค๋ ˆ๋“œ๊ฐ€ ์“ธ ์˜
์—ญ์„ ๋ฏธ๋ฆฌ ๊ธˆ์„ ๊ทธ์–ด ์ •ํ•ด๋†“๊ณ  ์“ฐ๋„๋ก ๋งŒ๋“œ๋Š” ๊ฒƒ์ด๋‹ค. ๋”ฐ๋ผ์„œ ๊ฐ ์Šค๋ ˆ๋“œ๊ฐ€ ์“ฐ๋Š” ์˜์—ญ์ด ๋‚˜๋‰˜์–ด ์žˆ๊ธฐ
๋•Œ๋ฌธ์— ๋™๊ธฐํ™” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š”๋‹ค. Thread cache๋Š” tcmalloc์˜ ๊ทธ๊ฒƒ๊ณผ ๋˜‘๊ฐ™๋‹ค. ์ž‘์€ ํฌ๊ธฐ์˜
ํ• ๋‹น์˜ ๊ฒฝ์šฐ tcmalloc์ฒ˜๋Ÿผ Arena ์˜์—ญ์„ ์‚ดํ”ผ์ง€ ์•Š๊ณ  ์ž์‹ ์ด ๊ฐ–๊ณ  ์žˆ๋Š” Thread cache์— ๋ฐ”๋กœ ํ• 
๋‹นํ•˜๊ฒŒ ํ•จ์œผ๋กœ์จ ์„ฑ๋Šฅ์„ ํ–ฅ์ƒ์‹œํ‚จ๋‹ค. ํฐ ๋งฅ๋ฝ์ด๋‚˜ ๊ตฌ์กฐ๋Š” tcmalloc์ด๋ž‘ ๋น„์Šทํ•œ ๊ฒƒ ๊ฐ™๋‹ค.

9

Object Pooling
ํ’€๋ง์ด๋ผ๋Š” ๊ฐœ๋…์€ ๊ธฐ๋ณธ์ ์œผ๋กœ ๋น„์šฉ์ด ํฐ ์ž‘์—…์ธ ํ• ๋‹น๊ณผ ํ•ด์ œ๋ฅผ ๋ฐ˜๋ณต์ ์œผ๋กœ ์ˆ˜ํ–‰ํ•˜๋ฉด์„œ ์ƒ๊ธฐ๋Š” ์„ฑ
๋Šฅ ์ €ํ•˜๋ฅผ ์ค„์ด๊ธฐ ์œ„ํ•ด ๊ณ ์•ˆ๋œ ๊ฒƒ์ด๋‹ค. ์–ด์ฐจํ”ผ ์ž์›์ด๋ผ๋Š” ๊ฑด ํ•œ ๋ฒˆ ํ• ๋‹นํ•˜๋ฉด ์žฌํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ฑด๋ฐ
๋ญํ•˜๋Ÿฌ ๋งค๋ฒˆ ๋‹ค์‹œ ํ• ๋‹นํ•˜๊ณ  ํ•ด์ œํ•˜๋ƒ! ๋ฏธ๋ฆฌ ์“ธ ๋งŒํผ ์ž์›์„ ํ™•๋ณดํ•ด๋†“๊ณ  ๊ทธ๊ฑธ ๋Œ๋ ค๊ฐ€๋ฉด์„œ ์“ฐ์ž. ์ •๋„
๋กœ ๋ณด๋ฉด ๋  ๋“ฏ ํ•˜๋‹ค. ๋”ฐ๋ผ์„œ ํ• ๋‹น๊ณผ ํ•ด์ œ๊ฐ€ ๊ต‰์žฅํžˆ ๋นˆ๋ฒˆํ•˜๊ฒŒ ์ผ์–ด๋‚˜๋Š” ๊ฒฝ์šฐ์— ํ’€์„ ์“ฐ๋ฉด ์„ฑ๋Šฅ ํ–ฅ์ƒ ํšจ
๊ณผ๋ฅผ ๋งŽ์ด ๋ณผ ์ˆ˜ ์žˆ์„ ๊ฒƒ์ด๋‹ค.
์˜ค๋ธŒ์ ํŠธ ํ’€๋ง์€ ์œ„์˜ ํ’€๋ง์„ ๊ฐ์ฒด์— ๋Œ€ํ•ด ์ ์šฉ์‹œํ‚จ ๊ฐœ๋…์ด๋‹ค. ๋ฏธ๋ฆฌ ์ผ์ •ํ•œ ์–‘๋งŒํผ์˜ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ด
๋‘๊ณ (pool), ๊ฑฐ๊ธฐ์„œ ํ•„์š”ํ•œ ๋งŒํผ ๊ฐ€์ ธ๋‹ค ์“ฐ๊ณ  ๊ทธ๊ฑธ ๋‹ค ์“ฐ๋ฉด ์‚ญ์ œํ•˜๋Š” ๊ฒŒ ์•„๋‹ˆ๋ผ ๋‹ค์‹œ ํ’€์— ๋ฐ˜๋‚ฉํ•˜๊ณ ,
๊ทธ๊ฑธ ๋‹ค์‹œ ๊บผ๋‚ด์„œ ์“ฐ๊ณ ... ๋ฅผ ๋ฐ˜๋ณตํ•ด์„œ ํ• ๋‹น๊ณผ ํ•ด์ œ์— ๋“œ๋Š” ๋น„์šฉ์„ ์ค„์ด๋Š” ๊ฒƒ์ด๋‹ค.

10

Memory Pooling
์˜ค๋ธŒ์ ํŠธ ํ’€๋ง๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์ด๋ฒˆ์—” ํ’€๋ง์„ ๋ฉ”๋ชจ๋ฆฌ์— ์ ์šฉ์‹œํ‚จ ๊ฐœ๋…์ด๋‹ค. ๋ฏธ๋ฆฌ ์“ธ ๋งŒํผ์˜ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ
ํ• ๋‹น๋ฐ›์€ ๋‹ค์Œ(pool), ๊ฑฐ๊ธฐ์„œ ํ•„์š”ํ•œ ๋งŒํผ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๊บผ๋‚ด์„œ ์“ฐ๊ณ  ๋‹ค ์“ฐ๋ฉด ๋‹ค์‹œ ๋ฐ˜๋‚ฉํ•˜๊ณ ๋ฅผ ๋ฐ˜๋ณตํ•˜๋Š”
๊ฒƒ์ด๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ• ๋‹นํ•˜๊ณ  ํ•ด์ œํ•˜๋Š” ์‹œ์Šคํ…œ ์ฝœ์ด ํ›จ์”ฌ ์ค„์–ด๋“ค๊ฒŒ ๋˜๋ฏ€๋กœ ์„ฑ๋Šฅ ์ƒ์—์„œ ์ด
์ ์„ ๋งŽ์ด ์–ป์„ ์ˆ˜ ์žˆ๋‹ค.
๋‹จ, ๋ฉ”๋ชจ๋ฆฌ ํ’€๋ง์€ ์˜ค๋ธŒ์ ํŠธ ํ’€๋ง๋ณด๋‹ค๋Š” ๊ณ ๋ คํ•ด์•ผํ•  ์‚ฌํ•ญ์ด ๋งŽ๋‹ค. ๊ฐ™์€ ํฌ๊ธฐ๋“ค๋กœ๋งŒ ๊ตฌ์„ฑ๋œ ์˜ค๋ธŒ์ 
ํŠธ ํ’€๊ณผ ๋‹ค๋ฅด๊ฒŒ ๋ฉ”๋ชจ๋ฆฌ ํ’€์—์„œ๋Š” ์„œ๋กœ ๋‹ค๋ฅธ ํฌ๊ธฐ์˜ ๋ฉ”๋ชจ๋ฆฌ๋“ค์ด ํ• ๋‹น๋˜๊ณ  ํ•ด์ œ๋  ์ˆ˜ ์žˆ๋‹ค. ๊ทธ ๋•Œ๋ฌธ์—
heap์—์„œ์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ fragmentation ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ ๋“ฑ์— ๋Œ€ํ•ด ๋”
๋งŽ์€ ์‹ ๊ฒฝ์„ ์จ์•ผํ•œ๋‹ค.

11

STL Allocator
๋ณดํ†ต STL์„ ์“ธ ๋•Œ ์šฐ๋ฆฌ๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•œ๋‹ค.
std::vector<int> vi;
ํ•˜์ง€๋งŒ ์‚ฌ์‹ค ์—ฌ๊ธฐ์—๋Š” ์ƒ๋žต๋œ ๊ฒŒ ์žˆ๋‹ค. ๋ฐ”๋กœ allocator ์ง€์ •์ด๋‹ค. allocator ํƒ€์ž…์„ ์ง€์ •ํ•˜์ง€ ์•Š์„
๊ฒฝ์šฐ STL์€ ๋‚ด๋ถ€์ ์œผ๋กœ ๊ธฐ๋ณธ allocator๋ฅผ ์ด์šฉํ•ด์„œ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ• ๋‹นํ•˜๊ณ  ํ•ด์ œํ•˜๋Š” ์ž‘์—…์„ ์ง„ํ–‰ํ•˜๋Š”
๋ฐ, ์ด๊ฑด ๋ฉ”๋ชจ๋ฆฌ ํ’€์„ ์ด์šฉํ•˜๊ฑฐ๋‚˜ ํ•˜๋Š” ๋ฐฉ์‹์ด ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— fragmentation ๋“ฑ์˜ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ• 
์ˆ˜ ์žˆ๋‹ค. ๋”ฐ๋ผ์„œ STL์—์„œ ๋ฉ”๋ชจ๋ฆฌ ํ’€์„ ์ ์šฉํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ์ง์ ‘ custom allocator๋ฅผ ์ž‘์„ฑํ•˜์—ฌ ํ•ด๋‹น
STL ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์ง์ ‘ ์ž‘์„ฑํ•œ ๋ฉ”๋ชจ๋ฆฌ ํ’€์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ• ๋‹น ํ•ด์ œ ๋™์ž‘์„ ์ง„ํ–‰ํ•˜๋„๋ก ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค.

12

STL Allocator
custom allocator์˜ ์กฐ๊ฑด
โ€ข	ํ…œํ”Œ๋ฆฟ์ด์–ด์•ผ ํ•œ๋‹ค.
STL ์ž์ฒด๊ฐ€ ์ž„์˜ ํƒ€์ž…์— ๋Œ€ํ•ด ๋™์ž‘ํ•˜๋ฏ€๋กœ ๋‹น์—ฐํ•œ ์ด์•ผ๊ธฐ๋‹ค. ํ…œํ”Œ๋ฆฟ์œผ๋กœ ์ž‘์„ฑ๋˜์–ด์•ผ ์ž„์˜ ํƒ€์ž…์— ๋Œ€
ํ•ด ์ œ๋Œ€๋กœ ๋™์ž‘ํ•˜๋Š” allocator๊ฐ€ ๋  ์ˆ˜ ์žˆ์„ ๊ฒƒ์ด๋‹ค.
โ€ข	pointer(T*)์™€ reference(T&)๋ผ๋Š” ํƒ€์ž…์„ ์ œ๊ณตํ•ด์•ผํ•œ๋‹ค.
STL ์ปจํ…Œ์ด๋„ˆ ๋‚ด๋ถ€ ๊ตฌํ˜„์—์„œ ํ•ด๋‹น ํƒ€์ž…๋“ค์„ ์‚ฌ์šฉํ•œ๋‹ค.
โ€ข	๋น„์ •์  ๋ฐ์ดํ„ฐ ๋ฉค๋ฒ„๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์—†๋‹ค.
๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น์„ ๋‹ด๋‹นํ•˜๋Š” Allocator๊ฐ€ ๊ฐœ๋ณ„ ์ƒํƒœ(๋ฉค๋ฒ„ ๋ณ€์ˆ˜)๋ฅผ ๊ฐ€์ง„๋‹ค๋Š” ๊ฒƒ ์ž์ฒด๊ฐ€ ๋ง์ด ์•ˆ ๋œ๋‹ค.
โ€ข	์ค‘์ฒฉ template์„ ์ œ๊ณตํ•ด์•ผํ•œ๋‹ค(rebind)
list ๋“ฑ์˜ node์—์„œ ์ง€์ •๋œ Tํƒ€์ž…๋ณด๋‹ค ํฐ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ํ•„์š”ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

13

STL Allocator
์˜ˆ์‹œ
template <typename T>
class customAllocator
{
public:
	 using value_type = T;
	 using pointer = value_type*;
	 using const_pointer = const value_type*;
	 using reference = value_type&;
	 using const_reference = const value_type&;
	 template <typename U>
	 struct rebind
	{
		using other = customAllocator<U>;
	};
	 void construct(pointer p, const T& t); // ์ƒ์„ฑ์ž ํ˜ธ์ถœ
	 void destroy(pointer p); // ์†Œ๋ฉธ์ž ํ˜ธ์ถœ
	 T* allocate(size_t n); // ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น ( ๋ฉ”๋ชจ๋ฆฌ ํ’€์—์„œ ๊ฐ€์ ธ์˜ค๊ธฐ ) - ์ธ์ž๋Š” ๊ฐ์ฒด ๊ฐœ์ˆ˜ ๊ธฐ์ค€
	 void deallocate(T* ptr, size_t n); // ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น ํ•ด์ œ ( ๋ฐ˜๋‚ฉ )
private:
};
allocate ,deallocate ํ•จ์ˆ˜๋ฅผ ์ ์ ˆํžˆ ๋ฉ”๋ชจ
๋ฆฌ ํ’€์—์„œ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๊ฐ€์ ธ์˜ค๊ณ  ๋ฐ˜๋‚ฉํ•˜๋„๋ก ๋งŒ
๋“ค๋ฉด ๋ฉ”๋ชจ๋ฆฌ ํ’€์„ ์ด์šฉํ•˜๋Š” STL container
๋ฅผ ์ด์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ด๋‹ค

More Related Content

Memory & object pooling

  • 1. Memory & Object Pooling NHN NEXT ๋‚จํ˜„์šฑ
  • 2. Windows LFH ์žฆ์€ ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น / ํ•ด์ œ์˜ ๋ฐ˜๋ณต์‹œ ํž™์— ๋‚จ์€ ๋ฉ”๋ชจ๋ฆฌ์˜ ์–‘์ด ์ถฉ๋ถ„ํ•จ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  ๋” ์ด์ƒ ๋ฉ”๋ชจ๋ฆฌ์˜ ํ• ๋‹น์„ ์ง„ํ–‰ํ•  ์ˆ˜ ์—†๋Š” ์ƒํ™ฉ์ด ์ƒ๊ธด๋‹ค. ์ด๋ฅผ Heap fragmentation์ด๋ผ๊ณ  ํ•˜๋Š”๋ฐ, LFH๋Š” ์ด ํ˜„์ƒ ์„ ์ค„์ด๊ธฐ ์œ„ํ•ด ๊ณ ์•ˆ๋œ ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น ์ •์ฑ…์ด๋‹ค. Heap - ๋นจ๊ฐ• : ํ• ๋‹น๋จ, ํฐ์ƒ‰ : ํ• ๋‹น ์•ˆ ๋จ ์ด ์ •๋„ ํฌ๊ธฐ ํ• ๋‹นํ•˜๋ ค๊ณ  ํ•  ๋•Œ ํž™์— ์—ฌ์œ  ๊ณต๊ฐ„์ด ์ถฉ๋ถ„ํžˆ ๋‚จ์•„ ์žˆ์Œ์—๋„ ๋ถˆ ๊ตฌํ•˜๊ณ  ๋ถ€๋ถ„๋ถ€๋ถ„ ์ž˜๋ ค์žˆ์–ด ํ• ๋‹น์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค!! -> fragmentation
  • 3. Windows LFH LFH๋Š” ์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด 128๊ฐœ์˜ ์„œ๋กœ ๋‹ค๋ฅธ ํฌ๊ธฐ์˜ bucket์„ ๋ฏธ๋ฆฌ ๊ตฌ์„ฑํ•œ ํ›„, ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น ์š”์ฒญ ์ด ์ผ์–ด๋‚ฌ์„ ๋•Œ ํ•ด๋‹น ์‚ฌ์ด์ฆˆ๋ฅผ ํฌํ•จํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ€์žฅ ์ž‘์€ ํฌ๊ธฐ์˜ bucket์„ ์„ ํƒํ•ด ๊ฑฐ๊ธฐ ํ• ๋‹นํ•œ๋‹ค. Buckets Granularity(์ฆ๊ฐ€ํญ) Range(์‚ฌ์ด์ฆˆ ๋ฒ”์œ„) 1 - 32 8 1-256 33 - 48 16 257-512 49 - 64 32 513-1024 65 - 80 64 1025-2048 81 - 96 128 2049-4096 97 - 112 256 4097-8192 113 - 128 512 8193-16384 ๋”ฐ๋ผ์„œ ๋ฒ„ํ‚ท ์‚ฌ์ด์ฆˆ๋Š” ์ฐจ๋ก€๋Œ€๋กœ 1๋ฒˆ = 8Bytes, 2๋ฒˆ = 16Bytes, 3๋ฒˆ = 24Bytes, 4๋ฒˆ = 32Bytes... ํฌ๊ธฐ๊ฐ€ ๋œ๋‹ค. ๋งŒ์•ฝ 21Byte ํฌ๊ธฐ์˜ ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น ์š”์ฒญ์ด ๋“ค์–ด์˜จ๋‹ค๋ฉด ํ•ด๋‹น ํฌ๊ธฐ๋ฅผ ์ˆ˜์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ€์žฅ ์ž‘์€ ํฌ๊ธฐ์˜ ๋ฒ„ํ‚ท์€ 24Bytes ์‚ฌ์ด์ฆˆ์˜ 3๋ฒˆ ๋ฒ„ํ‚ท์ด๋ฏ€๋กœ 3๋ฒˆ ๋ฒ„ํ‚ท์ด ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น์— ์“ฐ์ธ๋‹ค.
  • 4. Windows LFH LFH๋ฅผ ์“ฐ๊ธฐ ์œ„ํ•œ ์ „์ œ ์กฐ๊ฑด์ด ์žˆ๋‹ค(์•„๋ž˜ ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜์ง€ ์•Š์œผ๋ฉด LFH๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค). โ€ข ํ• ๋‹น ํฌ๊ธฐ๋Š” 16kb๋ณด๋‹ค ์ž‘์•„์•ผํ•œ๋‹ค. ์•ž์˜ ํ‘œ์—์„œ๋„ ๋ณผ ์ˆ˜ ์žˆ์ง€๋งŒ 16kb๋ณด๋‹ค ํฐ ํฌ๊ธฐ์˜ bucket์€ ์—†๊ธฐ ๋•Œ๋ฌธ์— ์–ด์ฐŒ๋ณด๋ฉด ๋‹น์—ฐํ•˜๋‹ค. โ€ข HEAP_NO_SERIALIZE(๊ผญ ์ˆœ์ฐจ์ ์œผ๋กœ ์ ‘๊ทผํ•˜์ง€ ์•Š์•„๋„ ๋˜๋ฉฐ ์ ‘๊ทผ์‹œ lock์ด ๊ฑธ๋ฆฌ์ง€ ์•Š๋Š” heap) ๋กœ ์ƒ์„ฑ๋œ heap์—๋Š” ์‚ฌ์šฉ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค. โ€ข ๊ณ ์ • ํฌ๊ธฐ(Fixed Size)๋กœ ์ƒ์„ฑ๋œ heap์—๋Š” ์ ์šฉ์ด ๋˜์ง€ ์•Š๋Š”๋‹ค. โ€ข ๋””๋ฒ„๊น… ํˆด์—์„œ๋Š” LFH๊ฐ€ ๋™์ž‘ํ•˜์ง€ ์•Š๋Š”๋‹ค. ๊ทธ๋ฆฌ๊ณ  ํ•œ ๋ฒˆ LFH๋ฅผ ์ ์šฉ์‹œํ‚ค๋ฉด ์ด๊ฑธ ๋˜๋Œ๋ฆฌ๋Š” ๊ฒƒ์€ ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค. LFH๋Š” 16KB ๋ฏธ๋งŒ์˜ ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น์ด ๋นˆ๋ฒˆํ•˜๊ฒŒ ์ผ์–ด๋‚˜๋Š” ๋ฉ€ํ‹ฐ ์Šค๋ ˆ๋“œ ํ™˜๊ฒฝ์—์„œ ๋›ฐ์–ด๋‚œ ์„ฑ๋Šฅ์„ ๋ณด์ธ ๋‹ค๊ณ  ํ•œ๋‹ค.
  • 5. Windows LFH ์‚ฌ์šฉ๋ฒ•. ๋งค์šฐ ๊ฐ„๋‹จํ•˜๋‹ค. windows Vista ์ด์ƒ๋ถ€ํ„ฐ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ LFH๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๊ณ  ํ•œ๋‹ค. ULONG heapFragValue = 2; HeapSetInformation(GetProcessHeap(), //default heap์˜ ํ•ธ๋“ค์„ ๋ฐ›์•„์˜ด HeapCompatibilityInformation, &HeapFragValue, sizeof(HeapFragValue)); ์œ„ ์ฝ”๋“œ๋ฅผ ์ˆ˜ํ–‰ํ•˜๋ฉด Default Heap์ด LFH๋กœ ๋ฐ”๋€๋‹ค. ์ด์ œ ๊ทธ๋ƒฅ new delete ์“ฐ๋ฉด ์ž๋™์œผ๋กœ LFH์˜ ์ •์ฑ…์— ๋”ฐ๋ผ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ํ• ๋‹น๋œ๋‹ค.
  • 6. Windows LFH Windows Internals์˜ LFH์— ๋Œ€ํ•œ ์„ค๋ช… - ๋ฉ€ํ‹ฐ ์Šค๋ ˆ๋“œ์—์„œ ์ž˜ ๋™์ž‘ํ•˜๋Š” ์ด์œ ? ... The LFH addresses these issues(* fragmentation) by using the core heap manager and look-aside lists. The Windows heap manager implements an automatic tuning algorithm that can enable the LFH by default under certain conditions, such as lock contention or the presence of popular size allocations that have shown better performance with the LFH enabled. For large heaps, a significant percentage of allocations is frequently grouped in a relatively small number of buckets of certain sizes. The allocation strategy used by LFH is to optimize the usage for these patterns by efficiently handling same-size blocks. To address scalability, the LFH expands the frequently accessed internal structures to a number of slots that is two times larger than the current number of processors on the machine. The assignment of threads to these slots is done by an LFH component called the affinity manager. Initially, the LFH starts using the first slot for heap allocations; however, if a contention is detected when accessing some internal data, the LFH switches the current thread to use a different slot. Further contentions will spread threads on more slots. These slots are controlled for each size bucket to improve locality and minimize the overall memory consumption. ... ๋ผ๊ณ  ์„ค๋ช…ํ•˜๊ณ  ์žˆ์œผ๋‚˜ ์†”์งํžˆ ๋ฌด์Šจ ์†Œ๋ฆฌ์ธ์ง€ ์ •ํ™•ํžˆ ์ดํ•ด๋ฅผ ๋ชปํ•˜๊ฒ ๋‹ค. ์ž์ฃผ ์ ‘๊ทผ๋˜๋Š” ๋‚ด๋ถ€ ๊ตฌ์กฐ์ฒด์— ๋Œ€ํ•ด ํ•ด๋‹น ์Šฌ๋กฏ์— ๋Œ€ํ•œ ์Šค๋ ˆ๋“œ์˜ ๋Œ€์ž…(assignment)์—์„œ lock contention์ด ์ผ์–ด๋‚˜๋ฉด ๋‹ค๋ฅธ ์Šฌ๋กฏ์„ ์“ฐ๊ฒŒ ํ•ด์ฃผ๋ฉฐ, ์Šฌ๋กฏ๋“ค์€ ๊ฐ ์‚ฌ์ด์ฆˆ์˜ ๋ฒ„ํ‚ท์— ์˜ํ•ด ์ œ์–ด๋œ๋‹ค๊ณ  ํ•œ๋‹ค(์ง€์—ญ์„ฑ๊ณผ ๋ฉ”๋ชจ๋ฆฌ ์†Œ๋ชจ ์ตœ์ ํ™”๋ฅผ ์œ„ํ•ด). ๊ทผ๋ฐ ์Šฌ๋กฏ์ด๋ž‘ ๋‚ด๋ถ€ ๊ตฌ์กฐ์ฒด, affinity manager๊ฐ€ ๋‹น์ตœ ์ •ํ™•ํžˆ ๋ญ”์ง€...
  • 7. Windows LFH ์•„๋ฌดํŠผ LFH ์„ฑ๋Šฅ์€ ๊ต‰์žฅํžˆ ์ข‹๋‹ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค. (๊ตฌ์Šน๋ชจ ๊ต์ˆ˜๋‹˜ ์˜คํ”ผ์…œ)
  • 8. tcmalloc / jemalloc tcmalloc์€ ์ด๋ฆ„๋ถ€ํ„ฐ thread cache malloc์œผ๋กœ, ๊ฐ ์Šค๋ ˆ๋“œ๋ณ„ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ์ž์™€ ์ค‘์•™ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ ์ž๋ฅผ ๊ตฌ๋ถ„ํ•˜์—ฌ ๊ด€๋ฆฌํ•œ๋‹ค. ์ž‘์€ ํฌ๊ธฐ(32kb)์˜ ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น์€ ์Šค๋ ˆ๋“œ๋ณ„ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ์ž์—์„œ ํ• ๋‹นํ•˜ ๊ณ , ๊ทธ๋ณด๋‹ค ํฐ ํฌ๊ธฐ์˜ ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น์€ ์ค‘์•™ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ์ž๋กœ๋ถ€ํ„ฐ ๋ฐ›์•„์˜ค๋„๋ก ๋งŒ๋“ค์–ด์„œ ์ž‘์€ ๋ฉ”๋ชจ๋ฆฌ์˜ ํ• ๋‹น์ด ์žฆ๊ฒŒ ์ผ์–ด๋‚˜๋Š” ์ƒํ™ฉ์—์„œ๋Š” heap์˜ lock ๋•Œ๋ฌธ์— ๋ฐœ์ƒํ•˜๋Š” ์„ฑ๋Šฅ ์ €ํ•˜๊ฐ€ ์—†์–ด์„œ ์ข‹์€ ํšจ์œจ์„ ๋ณด์ธ๋‹ค. jemalloc์€ ํฌ๊ฒŒ Arena์™€ Thread cache๋ผ๋Š” ๋‘ ๊ฐœ์˜ ํ•ต์‹ฌ ๊ตฌ์กฐ๋กœ ์ด๋ฃจ์–ด์ ธ ์žˆ๋‹ค. Arena๋Š” ๋ฉ”๋ชจ ๋ฆฌ๋ฅผ ์ž‘์€ ๋ฉ์–ด๋ฆฌ๋กœ ์ž˜๋ผ ๊ฐ ์Šค๋ ˆ๋“œ์—๊ฒŒ ๋‚˜๋ˆ„์–ด ์ค€ ์˜์—ญ์ด๋‹ค. ์ฆ‰ ์ „์ฒด ํž™์—์„œ ๊ฐ๊ฐ์˜ ์Šค๋ ˆ๋“œ๊ฐ€ ์“ธ ์˜ ์—ญ์„ ๋ฏธ๋ฆฌ ๊ธˆ์„ ๊ทธ์–ด ์ •ํ•ด๋†“๊ณ  ์“ฐ๋„๋ก ๋งŒ๋“œ๋Š” ๊ฒƒ์ด๋‹ค. ๋”ฐ๋ผ์„œ ๊ฐ ์Šค๋ ˆ๋“œ๊ฐ€ ์“ฐ๋Š” ์˜์—ญ์ด ๋‚˜๋‰˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋™๊ธฐํ™” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š”๋‹ค. Thread cache๋Š” tcmalloc์˜ ๊ทธ๊ฒƒ๊ณผ ๋˜‘๊ฐ™๋‹ค. ์ž‘์€ ํฌ๊ธฐ์˜ ํ• ๋‹น์˜ ๊ฒฝ์šฐ tcmalloc์ฒ˜๋Ÿผ Arena ์˜์—ญ์„ ์‚ดํ”ผ์ง€ ์•Š๊ณ  ์ž์‹ ์ด ๊ฐ–๊ณ  ์žˆ๋Š” Thread cache์— ๋ฐ”๋กœ ํ•  ๋‹นํ•˜๊ฒŒ ํ•จ์œผ๋กœ์จ ์„ฑ๋Šฅ์„ ํ–ฅ์ƒ์‹œํ‚จ๋‹ค. ํฐ ๋งฅ๋ฝ์ด๋‚˜ ๊ตฌ์กฐ๋Š” tcmalloc์ด๋ž‘ ๋น„์Šทํ•œ ๊ฒƒ ๊ฐ™๋‹ค.
  • 9. Object Pooling ํ’€๋ง์ด๋ผ๋Š” ๊ฐœ๋…์€ ๊ธฐ๋ณธ์ ์œผ๋กœ ๋น„์šฉ์ด ํฐ ์ž‘์—…์ธ ํ• ๋‹น๊ณผ ํ•ด์ œ๋ฅผ ๋ฐ˜๋ณต์ ์œผ๋กœ ์ˆ˜ํ–‰ํ•˜๋ฉด์„œ ์ƒ๊ธฐ๋Š” ์„ฑ ๋Šฅ ์ €ํ•˜๋ฅผ ์ค„์ด๊ธฐ ์œ„ํ•ด ๊ณ ์•ˆ๋œ ๊ฒƒ์ด๋‹ค. ์–ด์ฐจํ”ผ ์ž์›์ด๋ผ๋Š” ๊ฑด ํ•œ ๋ฒˆ ํ• ๋‹นํ•˜๋ฉด ์žฌํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ฑด๋ฐ ๋ญํ•˜๋Ÿฌ ๋งค๋ฒˆ ๋‹ค์‹œ ํ• ๋‹นํ•˜๊ณ  ํ•ด์ œํ•˜๋ƒ! ๋ฏธ๋ฆฌ ์“ธ ๋งŒํผ ์ž์›์„ ํ™•๋ณดํ•ด๋†“๊ณ  ๊ทธ๊ฑธ ๋Œ๋ ค๊ฐ€๋ฉด์„œ ์“ฐ์ž. ์ •๋„ ๋กœ ๋ณด๋ฉด ๋  ๋“ฏ ํ•˜๋‹ค. ๋”ฐ๋ผ์„œ ํ• ๋‹น๊ณผ ํ•ด์ œ๊ฐ€ ๊ต‰์žฅํžˆ ๋นˆ๋ฒˆํ•˜๊ฒŒ ์ผ์–ด๋‚˜๋Š” ๊ฒฝ์šฐ์— ํ’€์„ ์“ฐ๋ฉด ์„ฑ๋Šฅ ํ–ฅ์ƒ ํšจ ๊ณผ๋ฅผ ๋งŽ์ด ๋ณผ ์ˆ˜ ์žˆ์„ ๊ฒƒ์ด๋‹ค. ์˜ค๋ธŒ์ ํŠธ ํ’€๋ง์€ ์œ„์˜ ํ’€๋ง์„ ๊ฐ์ฒด์— ๋Œ€ํ•ด ์ ์šฉ์‹œํ‚จ ๊ฐœ๋…์ด๋‹ค. ๋ฏธ๋ฆฌ ์ผ์ •ํ•œ ์–‘๋งŒํผ์˜ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ด ๋‘๊ณ (pool), ๊ฑฐ๊ธฐ์„œ ํ•„์š”ํ•œ ๋งŒํผ ๊ฐ€์ ธ๋‹ค ์“ฐ๊ณ  ๊ทธ๊ฑธ ๋‹ค ์“ฐ๋ฉด ์‚ญ์ œํ•˜๋Š” ๊ฒŒ ์•„๋‹ˆ๋ผ ๋‹ค์‹œ ํ’€์— ๋ฐ˜๋‚ฉํ•˜๊ณ , ๊ทธ๊ฑธ ๋‹ค์‹œ ๊บผ๋‚ด์„œ ์“ฐ๊ณ ... ๋ฅผ ๋ฐ˜๋ณตํ•ด์„œ ํ• ๋‹น๊ณผ ํ•ด์ œ์— ๋“œ๋Š” ๋น„์šฉ์„ ์ค„์ด๋Š” ๊ฒƒ์ด๋‹ค.
  • 10. Memory Pooling ์˜ค๋ธŒ์ ํŠธ ํ’€๋ง๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์ด๋ฒˆ์—” ํ’€๋ง์„ ๋ฉ”๋ชจ๋ฆฌ์— ์ ์šฉ์‹œํ‚จ ๊ฐœ๋…์ด๋‹ค. ๋ฏธ๋ฆฌ ์“ธ ๋งŒํผ์˜ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ• ๋‹น๋ฐ›์€ ๋‹ค์Œ(pool), ๊ฑฐ๊ธฐ์„œ ํ•„์š”ํ•œ ๋งŒํผ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๊บผ๋‚ด์„œ ์“ฐ๊ณ  ๋‹ค ์“ฐ๋ฉด ๋‹ค์‹œ ๋ฐ˜๋‚ฉํ•˜๊ณ ๋ฅผ ๋ฐ˜๋ณตํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ• ๋‹นํ•˜๊ณ  ํ•ด์ œํ•˜๋Š” ์‹œ์Šคํ…œ ์ฝœ์ด ํ›จ์”ฌ ์ค„์–ด๋“ค๊ฒŒ ๋˜๋ฏ€๋กœ ์„ฑ๋Šฅ ์ƒ์—์„œ ์ด ์ ์„ ๋งŽ์ด ์–ป์„ ์ˆ˜ ์žˆ๋‹ค. ๋‹จ, ๋ฉ”๋ชจ๋ฆฌ ํ’€๋ง์€ ์˜ค๋ธŒ์ ํŠธ ํ’€๋ง๋ณด๋‹ค๋Š” ๊ณ ๋ คํ•ด์•ผํ•  ์‚ฌํ•ญ์ด ๋งŽ๋‹ค. ๊ฐ™์€ ํฌ๊ธฐ๋“ค๋กœ๋งŒ ๊ตฌ์„ฑ๋œ ์˜ค๋ธŒ์  ํŠธ ํ’€๊ณผ ๋‹ค๋ฅด๊ฒŒ ๋ฉ”๋ชจ๋ฆฌ ํ’€์—์„œ๋Š” ์„œ๋กœ ๋‹ค๋ฅธ ํฌ๊ธฐ์˜ ๋ฉ”๋ชจ๋ฆฌ๋“ค์ด ํ• ๋‹น๋˜๊ณ  ํ•ด์ œ๋  ์ˆ˜ ์žˆ๋‹ค. ๊ทธ ๋•Œ๋ฌธ์— heap์—์„œ์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ fragmentation ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ ๋“ฑ์— ๋Œ€ํ•ด ๋” ๋งŽ์€ ์‹ ๊ฒฝ์„ ์จ์•ผํ•œ๋‹ค.
  • 11. STL Allocator ๋ณดํ†ต STL์„ ์“ธ ๋•Œ ์šฐ๋ฆฌ๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•œ๋‹ค. std::vector<int> vi; ํ•˜์ง€๋งŒ ์‚ฌ์‹ค ์—ฌ๊ธฐ์—๋Š” ์ƒ๋žต๋œ ๊ฒŒ ์žˆ๋‹ค. ๋ฐ”๋กœ allocator ์ง€์ •์ด๋‹ค. allocator ํƒ€์ž…์„ ์ง€์ •ํ•˜์ง€ ์•Š์„ ๊ฒฝ์šฐ STL์€ ๋‚ด๋ถ€์ ์œผ๋กœ ๊ธฐ๋ณธ allocator๋ฅผ ์ด์šฉํ•ด์„œ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ• ๋‹นํ•˜๊ณ  ํ•ด์ œํ•˜๋Š” ์ž‘์—…์„ ์ง„ํ–‰ํ•˜๋Š” ๋ฐ, ์ด๊ฑด ๋ฉ”๋ชจ๋ฆฌ ํ’€์„ ์ด์šฉํ•˜๊ฑฐ๋‚˜ ํ•˜๋Š” ๋ฐฉ์‹์ด ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— fragmentation ๋“ฑ์˜ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค. ๋”ฐ๋ผ์„œ STL์—์„œ ๋ฉ”๋ชจ๋ฆฌ ํ’€์„ ์ ์šฉํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ์ง์ ‘ custom allocator๋ฅผ ์ž‘์„ฑํ•˜์—ฌ ํ•ด๋‹น STL ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์ง์ ‘ ์ž‘์„ฑํ•œ ๋ฉ”๋ชจ๋ฆฌ ํ’€์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ• ๋‹น ํ•ด์ œ ๋™์ž‘์„ ์ง„ํ–‰ํ•˜๋„๋ก ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค.
  • 12. STL Allocator custom allocator์˜ ์กฐ๊ฑด โ€ข ํ…œํ”Œ๋ฆฟ์ด์–ด์•ผ ํ•œ๋‹ค. STL ์ž์ฒด๊ฐ€ ์ž„์˜ ํƒ€์ž…์— ๋Œ€ํ•ด ๋™์ž‘ํ•˜๋ฏ€๋กœ ๋‹น์—ฐํ•œ ์ด์•ผ๊ธฐ๋‹ค. ํ…œํ”Œ๋ฆฟ์œผ๋กœ ์ž‘์„ฑ๋˜์–ด์•ผ ์ž„์˜ ํƒ€์ž…์— ๋Œ€ ํ•ด ์ œ๋Œ€๋กœ ๋™์ž‘ํ•˜๋Š” allocator๊ฐ€ ๋  ์ˆ˜ ์žˆ์„ ๊ฒƒ์ด๋‹ค. โ€ข pointer(T*)์™€ reference(T&)๋ผ๋Š” ํƒ€์ž…์„ ์ œ๊ณตํ•ด์•ผํ•œ๋‹ค. STL ์ปจํ…Œ์ด๋„ˆ ๋‚ด๋ถ€ ๊ตฌํ˜„์—์„œ ํ•ด๋‹น ํƒ€์ž…๋“ค์„ ์‚ฌ์šฉํ•œ๋‹ค. โ€ข ๋น„์ •์  ๋ฐ์ดํ„ฐ ๋ฉค๋ฒ„๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์—†๋‹ค. ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น์„ ๋‹ด๋‹นํ•˜๋Š” Allocator๊ฐ€ ๊ฐœ๋ณ„ ์ƒํƒœ(๋ฉค๋ฒ„ ๋ณ€์ˆ˜)๋ฅผ ๊ฐ€์ง„๋‹ค๋Š” ๊ฒƒ ์ž์ฒด๊ฐ€ ๋ง์ด ์•ˆ ๋œ๋‹ค. โ€ข ์ค‘์ฒฉ template์„ ์ œ๊ณตํ•ด์•ผํ•œ๋‹ค(rebind) list ๋“ฑ์˜ node์—์„œ ์ง€์ •๋œ Tํƒ€์ž…๋ณด๋‹ค ํฐ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ํ•„์š”ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
  • 13. STL Allocator ์˜ˆ์‹œ template <typename T> class customAllocator { public: using value_type = T; using pointer = value_type*; using const_pointer = const value_type*; using reference = value_type&; using const_reference = const value_type&; template <typename U> struct rebind { using other = customAllocator<U>; }; void construct(pointer p, const T& t); // ์ƒ์„ฑ์ž ํ˜ธ์ถœ void destroy(pointer p); // ์†Œ๋ฉธ์ž ํ˜ธ์ถœ T* allocate(size_t n); // ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น ( ๋ฉ”๋ชจ๋ฆฌ ํ’€์—์„œ ๊ฐ€์ ธ์˜ค๊ธฐ ) - ์ธ์ž๋Š” ๊ฐ์ฒด ๊ฐœ์ˆ˜ ๊ธฐ์ค€ void deallocate(T* ptr, size_t n); // ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น ํ•ด์ œ ( ๋ฐ˜๋‚ฉ ) private: }; allocate ,deallocate ํ•จ์ˆ˜๋ฅผ ์ ์ ˆํžˆ ๋ฉ”๋ชจ ๋ฆฌ ํ’€์—์„œ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๊ฐ€์ ธ์˜ค๊ณ  ๋ฐ˜๋‚ฉํ•˜๋„๋ก ๋งŒ ๋“ค๋ฉด ๋ฉ”๋ชจ๋ฆฌ ํ’€์„ ์ด์šฉํ•˜๋Š” STL container ๋ฅผ ์ด์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ด๋‹ค