ํฌ์ŠคํŠธ

Garbage-Collection

Garbage-Collection

๐Ÿ’ซ Q


  • ๊ฐ€๋น„์ง€์— ๋Œ€ํ•˜์—ฌ

  • GC์— ๋Œ€ํ•ด ์„ค๋ช…ํ•ด๋ด๋ผ
  • GC ์ตœ์ ํ™”๋ฅผ ์œ„ํ•ด ํ• ์ˆ˜์žˆ๋Š”์ผ์€ ๋ฌด์—‡์ด ์žˆ์„์ง€ ์„ค๋ช…ํ•ด๋ด๋ผ
  • GC์˜ ์žฅ์ ๊ณผ ๋‹จ์ ์— ๋Œ€ํ•ด ์„ค๋ช…ํ•ด๋ด๋ผ
  • ์„ธ๋Œ€๋ณ„ ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰์…˜
  • Unity
    • Instantiate/Destroy๋ฅผ ๋ฐ˜๋ณต์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ”๋ชจ๋ฆฌ ์ฆ๊ฐ€
    • -> ์˜ค๋ธŒ์ ํŠธ ํ’€ ์‚ฌ์šฉ

๐Ÿ’ซ Garbage


ํ”„๋กœ๊ทธ๋žจ์ด ๋™์ ์œผ๋กœ ํ• ๋‹นํ•œ ๋ฉ”๋ชจ๋ฆฌ ์ค‘์—์„œ ๋” ์ด์ƒ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๊ฐ€๋น„์ง€๋ผ๊ณ  ํ•œ๋‹ค.
๊ฐ€๋น„์ง€๋Š” ํ”„๋กœ๊ทธ๋žจ์˜ ์„ฑ๋Šฅ์„ ์ €ํ•˜์‹œํ‚ค๊ณ  ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๋ฅผ ๋ฐœ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰์…˜์„ ํ†ตํ•ด ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ•ด์ œํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.

๐Ÿ’ซ Garbage๊ฐ€ ์ƒ๊ธฐ๋Š” ์ƒํ™ฉ


๐Ÿซง ๋ฌธ์ž์—ด

1
2
string str = "Hello";
str = "World";

World๊ฐ€ ์ƒˆ๋กœ์šด ๋ฉ”๋ชจ๋ฆฌ์— ํ• ๋‹น๋˜๊ณ  Hello๋Š” ๋” ์ด์ƒ ์‚ฌ์šฉ๋˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ€๋น„์ง€๊ฐ€ ๋œ๋‹ค.

1
2
string str = "Hello";
str += "World";

HelloWorld๊ฐ€ ์ƒˆ๋กœ์šด ๋ฉ”๋ชจ๋ฆฌ์— ํ• ๋‹น๋˜๊ณ  Hello๋Š” ๋” ์ด์ƒ ์‚ฌ์šฉ๋˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ€๋น„์ง€๊ฐ€ ๋œ๋‹ค.

๋งŽ์€ ๋ฌธ์ž์—ด์„ ์กฐํ•ฉํ•˜๋Š” ๊ฒฝ์šฐ์—๋Š” StringBuilder๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ€๋น„์ง€๋ฅผ ์ค„์ผ ์ˆ˜ ์žˆ๋‹ค.
Append๋ฅผ ํ†ตํ•ด ๋ฏธ๋ฆฌ ํ• ๋‹น๋œ ๋ฉ”๋ชจ๋ฆฌ์— ๋ฌธ์ž์—ด์„ ๋ณต์‚ฌ๋งŒ ํ•ด๋’€๋‹ค๊ฐ€, ToString์„ ํ†ตํ•ด ํ•œ ๋ฒˆ์— ๋ฌธ์ž์—ด ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜ํ•œ๋‹ค.

1
2
3
4
StringBuilder sb = new StringBuilder();
sb.Append("Hello");
sb.Append("World");
string str = sb.ToString();

๐Ÿซง ๊ฐ์ฒด (new)

1
2
3
4
5
6
7
class MyClass
{
	public int value;
}

MyClass myClass = new MyClass();
myClass = new MyClass();
  • ํด๋ž˜์Šค๋ฅผ ์ธ์Šคํ„ด์‹ฑํ•˜๋ ค๋ฉด new๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.
  • new๋กœ ์ƒ์„ฑ๋œ ๊ฐ์ฒด๋Š” Heap์— ํ• ๋‹น๋˜๊ณ  Stack์—๋Š” Heap์— ํ• ๋‹น๋œ ๊ฐ์ฒด์˜ ์ฃผ์†Œ๊ฐ’์ด ์ €์žฅ๋œ๋‹ค.
  • ๋ฉ”์„œ๋“œ ์•ˆ์—์„œ new๋กœ ์ƒ์„ฑํ•œ ๊ฐ์ฒด๋Š” ๋ฉ”์„œ๋“œ๊ฐ€ ์ข…๋ฃŒ๋˜๋ฉด ๊ฐ€๋น„์ง€๊ฐ€ ๋œ๋‹ค.
  • -> ๋ฉ”์„œ๋“œ๊ฐ€ ์ž์ฃผ ํ˜ธ์ถœ๋˜๋Š” ๊ฒฝ์šฐ์—๋Š” ๊ฐ€๋น„์ง€๊ฐ€ ๋น ๋ฅด๊ฒŒ ์Œ“์ผ ์ˆ˜ ์žˆ๋‹ค.

  • ํด๋ž˜์Šค ๋Œ€์‹  ๊ตฌ์กฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด (๊ฐ€๋Šฅํ•˜๋‹ค๋ฉด) Stack์— ํ• ๋‹น๋˜๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ€๋น„์ง€๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š”๋‹ค.

๐Ÿซง Boxing, Unboxing

1
2
3
int num = 10;
object obj = num;
int num2 = (int)obj;

๐Ÿซง ์ด์ค‘ ์ฐธ์กฐ

1
2
MyClass myClass = new MyClass();
MyClass myClass2 = myClass;
  • myClass์™€ myClass2๋Š” ๊ฐ™์€ ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ•˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋‘˜ ์ค‘ ํ•˜๋‚˜๋งŒ ์ฐธ์กฐํ•˜๊ณ  ์žˆ์–ด๋„ ๊ฐ€๋น„์ง€๊ฐ€ ๋˜์ง€ ์•Š๋Š”๋‹ค.

๐Ÿ’ซ GC


๋™์ ์œผ๋กœ Garbage๋ฅผ ์ž๋™์œผ๋กœ ํƒ์ง€ํ•˜๊ณ  ํ•ด์ œํ•˜๋Š” ๋ฉ”๋ชจ๋ฆฌ ๊ธฐ๋ฒ•.
์ด๋Š” ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜์™€ ๊ฐ™์€ ๋ฌธ์ œ์ ์„ ๋ฐฉ์ง€ํ•˜์—ฌ ํ”„๋กœ๊ทธ๋žจ์˜ ์•ˆ์ •์„ฑ๊ณผ ์„ฑ๋Šฅ์„ ํ–ฅ์ƒํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•œ๋‹ค.

๐Ÿซง ์„ธ๋Œ€๋ณ„ GC

์„ธ๋Œ€๊ฐ€ ๋‚ฎ์€ ๋ฉ”๋ชจ๋ฆฌ๋ถ€ํ„ฐ ๋ฉ”๋ชจ๋ฆฌ ํ•ด์ œ๋ฅผ ํ•ด์ค€ ๋‹ค์Œ ๋ฉ”๋ชจ๋ฆฌ ์ปดํŽ™์…˜์„ ํ•ด์ค€๋‹ค.

  • 0์„ธ๋Œ€ : GC๋ฅผ ํ•œ๋ฒˆ๋„ ๊ฒช์ง€ ์•Š์€ ๊ฐ“ ์ƒ์„ฑ๋œ ๊ฐ์ฒด๊ฐ€ ๋Œ€์ƒ
  • 1์„ธ๋Œ€ : GC๋ฅผ 1ํšŒ ๊ฒช์€ ๊ฐ์ฒด๊ฐ€ ๋Œ€์ƒ
  • 2์„ธ๋Œ€ : GC๋ฅผ 2ํšŒ ์ด์ƒ ๊ฒช์€ ๊ฐ์ฒด๊ฐ€ ๋Œ€์ƒ(์ „์ฒด๋ฅผ ์˜๋ฏธ)
    • 2์„ธ๋Œ€ GC๋ฅผ ํ•  ์‹œ Full Garbage Collection์ด๋ผ ํ•˜๊ณ  ์ „์ฒด Heap์— ๋Œ€ํ•˜์—ฌ GCํ•˜๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค.

๐Ÿซง ์„ธ๋Œ€๋ฅผ ๋‚˜๋ˆ„๋Š” ๊ทผ๊ฑฐ

  • ์ตœ๊ทผ์— ์ƒ์„ฑ๋œ ๊ฐ์ฒด์ผ์ˆ˜๋ก ์ƒ๋ช…์ฃผ๊ธฐ๊ฐ€ ์งง์„ ๊ฐ€๋Šฅ์„ฑ์ด๋†’๊ณ , ์˜ค๋ž˜๋œ ๊ฐ์ฒด์ผ์ˆ˜๋ก ์ƒ๋ช…์ฃผ๊ธฐ๊ฐ€ ๊ธธ ๊ฐ€๋Šฅ์„ฑ์ด ๋†’์Šต๋‹ˆ๋‹ค.
  • ์ตœ๊ทผ์— ์ƒ์„ฑ๋œ ๊ฐ์ฒด๋ผ๋ฆฌ๋Š” ์„œ๋กœ ์—ฐ๊ด€์„ฑ์ด ๋†’์„ ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๋น„์Šทํ•œ ์‹œ์ ์— ์ž์ฃผ ์•ก์„ธ์Šค ๋ฉ๋‹ˆ๋‹ค.
  • ์ผ๋ถ€๋ถ„ Heap์— ๋Œ€ํ•ด GC๋ฅผ ํ•˜๋Š” ๊ฒƒ์ด ์ „์ฒด GC๋ฅผ ํ•˜๋Š” ๊ฒƒ ๋ณด๋‹ค ๋น ๋ฆ…๋‹ˆ๋‹ค.

๐Ÿซง ์–ธ์–ด์—์„œ

  • ๋งค๋‹ˆ์ง€๋“œ ์–ธ์–ด (GC ์ง€์›)
    • C# : .NET ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ ์‹คํ–‰.
  • ์–ธ๋งค๋‹ˆ์ง€๋“œ ์–ธ์–ด
    • C++ : ์ง์ ‘ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ• ๋‹นํ•˜๊ณ  ํ•ด์ œ.

๐Ÿ’ซ C#


๐Ÿซง GC

1
2
3
4
5
6
GC.Collect(); // ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰์…˜ ๊ฐ•์ œ ์ˆ˜ํ–‰
GC.Collect(0); // 0์„ธ๋Œ€ ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰์…˜ ๊ฐ•์ œ ์ˆ˜ํ–‰
GC.Collect(0, GCCollectionMode.Forced); // 0์„ธ๋Œ€ ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰์…˜ ๊ฐ•์ œ ์ˆ˜ํ–‰
GC.WaitForPendingFinalizers(); // ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰์…˜ ์™„๋ฃŒ ๋Œ€๊ธฐ
GC.WaitForFullGCComplete(); // ์ „์ฒด ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰์…˜ ์™„๋ฃŒ ๋Œ€๊ธฐ
GC.GetTotalMemory(true); // ์ „์ฒด ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰ ๋ฐ˜ํ™˜

๐Ÿซง Dispose Pattern

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public class MyClass : IDisposable
{
	private bool disposed = false;

	public void Dispose()
	{
		Dispose(true);
		GC.SuppressFinalize(this);
	}

	protected virtual void Dispose(bool disposing)
	{
		if (!disposed)
		{
			if (disposing)
			{
				// ๊ด€๋ฆฌ๋˜๋Š” ์ž์› ํ•ด์ œ
			}

			// ๋น„๊ด€๋ฆฌ ์ž์› ํ•ด์ œ
			disposed = true;
		}
	}

	~MyClass()
	{
		Dispose(false);
	}
}
  • IDisposable : ๊ด€๋ฆฌ๋˜๋Š” ์ž์›๊ณผ ๋น„๊ด€๋ฆฌ ์ž์›์„ ํ•ด์ œํ•˜๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ์ •์˜ํ•˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค
    • ์ง์ ‘ ๋ฉ”์„œ๋“œ๋ฅผ ๋งŒ๋“ค์–ด ์“ธ ์ˆ˜๋„ ์žˆ์ง€๋งŒ, IDisposable ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ƒ์†๋ฐ›์•„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.
      • ์„œ๋กœ ๋‹ค๋ฅธ Type์˜ ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•ด๋„, ๋™์ผํ•œ ์ฝ”๋“œ/๋ฐฉ๋ฒ•์œผ๋กœ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ•ด์ œํ•  ์ˆ˜ ์žˆ๋‹ค.
      • Dispose ๋ฉ”์„œ๋“œ๋งŒ ๋ณด๊ณ ๋„ โ€˜์•„, ํด๋ž˜์Šค ์‚ฌ์šฉ์ด ๋๋‚˜๋ฉด Dispose๋ฅผ ํ˜ธ์ถœํ•ด์•ผ๊ฒ ๊ตฌ๋‚˜โ€™ ๋ผ๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.
  • Dispose : ๊ด€๋ฆฌ๋˜๋Š” ์ž์›๊ณผ ๋น„๊ด€๋ฆฌ ์ž์›์„ ํ•ด์ œ
    • Dispose(true) : ๊ด€๋ฆฌ๋˜๋Š” ์ž์›์„ ํ•ด์ œ
    • Dispose(false) : ๋น„๊ด€๋ฆฌ ์ž์›์„ ํ•ด์ œ
  • GC.SuppressFinalize(this) : ํŒŒ๊ดด์ž๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ์•Š๋„๋ก ์„ค์ •

FileStream ๊ด€๋ จ ๊ฐ์ฒด์—์„œ ๋งŽ์ด ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

๐Ÿซง WeakReference

1
WeakReference weakReference = new WeakReference(new MyClass());
  • WeakReference : ์•ฝํ•œ ์ฐธ์กฐ
  • WeakReference๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰์…˜ ๋Œ€์ƒ์ด ๋˜์ง€ ์•Š๋Š”๋‹ค.
์ด ๊ธฐ์‚ฌ๋Š” ์ €์ž‘๊ถŒ์ž์˜ CC BY 4.0 ๋ผ์ด์„ผ์Šค๋ฅผ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค.