맨위로가기

쓰레기 (컴퓨터 과학)

"오늘의AI위키"는 AI 기술로 일관성 있고 체계적인 최신 지식을 제공하는 혁신 플랫폼입니다.
"오늘의AI위키"의 AI를 통해 더욱 풍부하고 폭넓은 지식 경험을 누리세요.

1. 개요

컴퓨터 과학에서 쓰레기는 프로그램에서 더 이상 사용되지 않지만 메모리에 남아있는 객체나 데이터를 의미한다. 쓰레기는 크게 구문적 쓰레기와 의미적 쓰레기로 나뉘며, 구문적 쓰레기는 프로그램의 루트 집합에서 도달할 수 없는 데이터, 의미적 쓰레기는 프로그램 입력 조합에서 접근되지 않는 데이터를 의미한다. 쓰레기는 메모리 부족 오류를 야기할 수 있으며, 가비지 수집을 통해 제거할 수 있다. 쓰레기 제거 방식에는 운영체제에 의한 회수, 수동 메모리 관리, 자동 가비지 컬렉션, 타입 이론적 접근 등이 있다.

더 읽어볼만한 페이지

  • 컴퓨터 데이터 - 헤더 (컴퓨팅)
    헤더는 전자 통신, 네트워킹, 파일 형식, 프로그래밍 등 다양한 분야에서 데이터의 전송 및 처리에 필요한 정보를 제공하는 정보의 집합이다.
  • 컴퓨터 데이터 - 데이터 손실
    데이터 손실은 절차적 요인, 인적 행위, 시스템 실패, 자연 재해, 범죄 등 다양한 원인으로 발생하며, 금전적 손실과 평판 손상 등 심각한 결과를 초래하므로 강력한 암호, 이중 인증, 정기적인 백업 등의 예방 조치가 중요하다.
  • 컴퓨터 프로그래밍 - 순서도
    순서도는 컴퓨터 알고리즘이나 프로세스를 시각적으로 표현하는 도구로, 흐름 공정 차트에서 기원하여 컴퓨터 프로그래밍 분야에서 알고리즘을 설명하는 데 사용되며, 다양한 종류와 소프트웨어 도구가 존재한다.
  • 컴퓨터 프로그래밍 - 의사코드
    의사코드는 컴퓨터 과학 및 수치 계산 분야에서 알고리즘을 설명하기 위해 사용되는 비표준적인 언어로, 자연어와 프로그래밍 언어의 요소를 혼합하여 알고리즘의 논리적 흐름을 이해하기 쉽게 하고 프로그래머가 실제 코드로 구현하기 전에 알고리즘을 설계하고 검토하는 데 유용하다.
쓰레기 (컴퓨터 과학)

2. 분류

쓰레기는 일반적으로 두 종류로 분류된다.


  • 구문적 쓰레기는 프로그램의 메모리 공간 내에 있지만 프로그램의 루트 집합에서 도달할 수 없는 모든 객체 또는 데이터를 의미한다. 이는 추적 가비지 컬렉션에서 논의된 바와 같이 많은 알고리즘으로 결정될 수 있으며, 코드 분석이 아닌 데이터 분석만 필요하다.

  • 의미적 쓰레기는 프로그램이 실행되는 동안 어떤 프로그램 입력 조합에서도 접근되지 않는 객체 또는 데이터를 의미한다.


간단히 말해, 구문적 쓰레기는 "도달할 수 없는" 데이터이고, 의미적 쓰레기는 "도달하지 않을" 데이터이다. 구문적 쓰레기는 의미적 쓰레기의 하위 집합이다. 객체가 다른 객체를 사용하지 않더라도 참조를 보유하는 것이 가능하기 때문이다.

2. 1. 구문적 쓰레기 (Syntactic Garbage)

쓰레기는 일반적으로 두 종류로 분류된다.

  • 구문적 쓰레기는 프로그램의 메모리 공간 내에 있지만 프로그램의 루트 집합에서 도달할 수 없는 모든 객체 또는 데이터를 의미한다. 이는 추적 가비지 컬렉션에서 논의된 바와 같이 많은 알고리즘으로 결정될 수 있으며, 코드 분석이 아닌 데이터 분석만 필요하다.
  • 의미적 쓰레기는 프로그램이 실행되는 동안 어떤 프로그램 입력 조합에서도 접근되지 않는 객체 또는 데이터를 의미한다.


간단히 말해, 구문적 쓰레기는 "도달할 수 없는" 데이터이고, 의미적 쓰레기는 "도달하지 않을" 데이터이다. 구문적 쓰레기는 의미적 쓰레기의 하위 집합이다. 객체가 다른 객체를 사용하지 않더라도 참조를 보유하는 것이 가능하기 때문이다.

2. 2. 의미적 쓰레기 (Semantic Garbage)

쓰레기는 일반적으로 두 종류로 분류된다.

  • 시맨틱 가비지(semantic garbage): 어떠한 프로그램 입력들의 결합을 위해 실행 중인 프로그램이 전혀 접근하지 않는 객체나 데이터


쓰레기가 아닌 객체나 데이터는 살아있다(live)고 언급된다.

간단히 말해, 의미적 쓰레기는 "도달하지 않을" 데이터이다. 의미적 쓰레기는 도달할 수 없거나(따라서 구문적 쓰레기이기도 함), 도달할 수 있지만 접근되지 않을 데이터이다. 후자는 코드 분석이 필요하며, 일반적으로 결정 불가능 문제이다.

구문적 쓰레기는 의미적 쓰레기의 (일반적으로 엄격한) 하위 집합이다. 객체가 다른 객체를 사용하지 않더라도 참조를 보유하는 것이 완전히 가능하기 때문이다.

2. 3. 구문적 쓰레기와 의미적 쓰레기의 관계

구문적 쓰레기는 의미적 쓰레기의 (일반적으로 엄격한) 하위 집합이다. 객체가 다른 객체를 사용하지 않더라도 참조를 보유하는 것이 가능하기 때문이다.

3. 예시

다음은 자바의 간단한 스택 구현 예시이다.



public class Stack {

private Object[] elements;

private int size;

public Stack(int capacity) {

elements = new Object[capacity];

}

public void push(Object e) {

elements[size++] = e;

}

public Object pop() {

return elements[--size];

}

}



스택에서 팝(pop)된 각 요소는 외부 참조가 없어지면 의미상 쓰레기가 된다. 이는 `elements[]`가 여전히 객체 참조를 포함하지만, 해당 객체는 이 참조를 통해 다시는 접근되지 않기 때문이다. `elements[]`는 클래스에 private로 지정되어 있고, `pop` 메서드는 이미 꺼내지 않은 요소들의 참조만 반환한다. (size 감소 이후 이 클래스는 해당 요소로 다시는 접근하지 못한다.) 그러나 이러한 일을 인지하는 일에는 클래스의 코드 분석이 요구되며, 일반적으로 예측하지 못하는 사항이다.

나중에 `push` 호출이 스택을 이전 크기로 다시 증가시킨다면, 이 마지막 참조를 덮어쓰며 해당 객체는 문법적 쓰레기가 되는데, 그 이유는 해당 객체를 다시는 접근하지 못하기 때문이며 이로써 쓰레기 수집 대상이 된다.

3. 1. 자바(Java) 스택 예제

다음은 자바의 간단한 스택 구현 예시이다.



public class Stack {

private Object[] elements;

private int size;

public Stack(int capacity) {

elements = new Object[capacity];

}

public void push(Object e) {

elements[size++] = e;

}

public Object pop() {

return elements[--size];

}

}



스택에서 팝(pop)된 각 요소는 외부 참조가 없어지면 의미상 쓰레기가 된다. 이는 `elements[]`가 여전히 객체 참조를 포함하지만, 해당 객체는 이 참조를 통해 다시는 접근되지 않기 때문이다. `elements[]`는 클래스에 private로 지정되어 있고, `pop` 메서드는 이미 꺼내지 않은 요소들의 참조만 반환한다. (size 감소 이후 이 클래스는 해당 요소로 다시는 접근하지 못한다.) 그러나 이러한 일을 인지하는 일에는 클래스의 코드 분석이 요구되며, 일반적으로 예측하지 못하는 사항이다.

나중에 `push` 호출이 스택을 이전 크기로 다시 증가시킨다면, 이 마지막 참조를 덮어쓰며 해당 객체는 문법적 쓰레기가 되는데, 그 이유는 해당 객체를 다시는 접근하지 못하기 때문이며 이로써 쓰레기 수집 대상이 된다.

3. 2. 파이썬(Python) 예제

파이썬 명령줄 인터프리터를 사용하면 참조 계수 쓰레기 수집을 통해 구문 쓰레기가 자동으로 수집되는 과정을 살펴볼 수 있다.



>>> class Foo:

... """This is an empty testing class."""

... pass

...

>>> bar = Foo()

>>> bar

<__main__.Foo object at 0x54f30>

>>> del bar



위 세션에서는 객체가 생성되고 메모리 내 위치가 표시된 후, 객체에 대한 유일한 참조가 삭제된다. 이 시점부터는 객체에 대한 참조가 없으므로 객체를 다시 사용할 수 없다.



>>> bar

Traceback (most recent call last):

File "", line 1, in ?

NameError: name 'bar' is not defined



객체를 참조하는 것이 불가능하므로 객체는 쓸모없어져 쓰레기가 된다. 파이썬은 쓰레기 수집을 통해 객체에 사용된 메모리를 자동으로 해제하여 다시 사용할 수 있게 한다.



>>> class Bar:

... """This is another testing class."""

... pass

...

>>> baz = Bar()

>>> baz

<__main__.Bar object at 0x54f30>



`Bar` 인스턴스는 이전 `Foo` 인스턴스가 위치했던 메모리 위치(0x54f30)에 생성된다. 이는 `Foo` 인스턴스가 파괴되어 메모리가 해제되었기 때문에 인터프리터가 동일한 메모리 위치에 `Bar` 객체를 생성하여 가용 자원을 효율적으로 활용한 결과이다.

3. 3. C 언어 예제

C 언어에서 변수는 선언만 되고 값이 할당되지 않은 채 사용될 수 있다. 예를 들어, 다음과 같은 C 언어 프로그램에서 변수 `x`는 선언만 되어 있고 값이 할당되지 않은 채 사용된다.[1]

```c

int main() {

int x;

printf("%d\n",x);

}

```

이때 `x`에는 '쓰레기 값'이 들어있다고 말하며, `x`의 값은 보장되지 않아 어떤 값이 출력될지 알 수 없다.[1] 이러한 쓰레기 값은 프로그램의 이상 동작을 유발하는 버그의 원인이 될 수 있다.[1] 특히, 포인터를 사용하여 메모리 내의 엉뚱한 곳에 값을 쓰는 경우, 디버깅이 매우 어려운 심각한 버그를 초래할 수 있다.

표준 규격에서는 이러한 변수의 값을 "부정"(indeterminate)으로 정의하며, 이러한 변수의 사용은 "미정의" 동작으로 간주된다.[1] 이는 프로그래머가 예기치 않은 결과를 초래할 수 있으므로 피해야 한다.

또한, 이러한 "쓰레기"는 컴퓨터 아키텍처와 정보 보안 관점에서 더 심각한 문제를 야기할 수 있다. 메모리 할당 단위인 "페이지"는 다른 프로세스나 커널과 공통적인 부분을 가질 수 있으며, 패스워드와 같은 기밀 정보를 포함할 수 있기 때문이다.

4. 쓰레기 제거 (Eliminating garbage)

쓰레기 할당 해제 관리는 컴퓨터 과학에서 중요한 문제 중 하나이다. 다음과 같은 몇 가지 접근 방식이 사용된다.


  • 많은 운영 체제는 프로세스나 프로그램이 종료될 때 해당 프로세스나 프로그램이 사용하던 메모리와 자원을 회수한다. 이러한 환경에서 실행되도록 설계된 단순하거나 수명이 짧은 프로그램은 종료될 수 있으며, 운영 체제가 필요한 회수를 수행할 수 있다.

  • 수동 메모리 관리를 사용하는 시스템이나 프로그래밍 언어에서는 더 이상 사용하지 않는 메모리를 프로그래머가 명시적으로 할당 해제해야 한다. C와 C++는 이 모델을 지원하는 잘 알려진 두 가지 언어이다.

  • 가비지 컬렉션은 다양한 알고리즘을 사용하여 프로그램의 상태를 자동으로 분석하고, 쓰레기를 식별하고, 프로그래머의 개입 없이 할당 해제한다. 자바 및 하스켈과 같은 많은 현대 프로그래밍 언어는 자동 가비지 컬렉션을 제공한다. 그러나 이는 LISP와 같은 오래된 언어에서도 사용되었으므로 최근 개발은 아니다.

  • 프로그램에서 쓰레기를 식별하고 제거하기 위한 타입 이론적 접근 방식(예: 영역 추론)에 대한 지속적인 연구가 진행되고 있다. 문제에 대한 일반적인 타입 이론적 해결책은 개발되지 않았다.

4. 1. 운영체제에 의한 회수

많은 운영 체제는 프로세스나 프로그램이 종료될 때 해당 프로세스나 프로그램이 사용하던 메모리와 자원을 회수한다. 이러한 환경에서 실행되도록 설계된 단순하거나 수명이 짧은 프로그램은 종료될 수 있으며, 운영 체제가 필요한 회수를 수행할 수 있다.

4. 2. 수동 메모리 관리

C와 C++와 같은 언어에서는 프로그래머가 명시적으로 메모리를 할당 해제해야 한다. 이러한 시스템에서는 더 이상 사용하지 않는 메모리를 프로그래머가 직접 관리해야 한다.

4. 3. 자동 쓰레기 수집 (Automatic Garbage Collection)

쓰레기 수집 (컴퓨터 과학)은 다양한 알고리즘을 사용하여 프로그램의 상태를 자동으로 분석하고, 쓰레기를 식별하여 할당 해제한다. 자바, 하스켈, 파이썬 등 많은 현대 프로그래밍 언어가 자동 가비지 컬렉션을 지원한다.

파이썬 명령줄 인터프리터를 사용하면 참조 계수 쓰레기 수집을 통해 구문 쓰레기를 자동으로 수집하는 예를 볼수 있다. 객체가 생성되고 메모리 내 위치가 표시되며, 객체에 대한 유일한 참조가 삭제되면 그 시점부터는 객체에 대한 참조가 없으므로 객체를 다시 사용할 수 없다. 파이썬은 쓰레기 수집을 사용하여 객체에 사용된 메모리를 자동으로 해제하여 다시 사용할 수 있게 한다. `Bar` 인스턴스는 이전 객체인 `Foo` 인스턴스가 위치했던 곳과 같은 메모리 위치에 생성이 되는데, 이는 `Foo` 인스턴스가 파괴되어 이를 포함하는 데 사용된 메모리가 해제되었으므로 인터프리터는 이전과 동일한 메모리 위치에 `Bar` 객체를 생성하여 사용 가능한 리소스를 잘 활용하기 때문이다.

많은 운영 체제는 프로세스나 프로그램이 종료될 때 해당 프로세스나 프로그램이 사용하던 메모리와 자원을 회수한다. 이러한 환경에서 실행되도록 설계된 단순하거나 수명이 짧은 프로그램은 종료될 수 있으며, 운영 체제가 필요한 회수를 수행할 수 있다. 수동 메모리 관리를 사용하는 시스템이나 프로그래밍 언어에서는 더 이상 사용하지 않는 메모리를 프로그래머가 명시적으로 할당 해제해야 한다. C와 C++는 이 모델을 지원하는 잘 알려진 두 가지 언어이다.

4. 4. 타입 이론적 접근

영역 추론과 같이, 프로그램에서 쓰레기를 식별하고 제거하기 위한 타입 이론적 접근 방식에 대한 연구가 진행되고 있다. 문제에 대한 일반적인 타입 이론적 해결책은 개발되지 않았다.

5. 영향 (Effects)

쓰레기는 힙 메모리를 소비하므로 메모리 부족 오류를 야기할 수 있다. 가비지는 힙 메모리를 소비하므로 메모리 사용을 최소화하고, 더 빠른 메모리 할당을 허용하며, 힙 조각화 및 메모리 사용 감소를 통해 메모리 부족 오류를 방지하기 위해 가비지를 수집하려 한다.

그러나 가비지 수집에는 시간이 걸리며, 수동으로 수행할 경우 코딩 오버헤드가 필요하다. 또한, 가비지 수집은 객체를 파괴하므로 파이널라이저 호출을 발생시킬 수 있으며, 프로그램 실행 중 임의의 지점에서 잠재적으로 임의의 코드를 실행한다. 잘못된 가비지 수집 (가비지가 아닌 메모리 할당 해제)은 주로 (가비지 수집기의 오류보다는) 수동 가비지 수집의 오류로 인해 메모리 안전 위반 (종종 보안 구멍을 생성함)을 야기하며, 이는 댕글링 포인터의 사용 때문이다.

구문적 가비지는 자동으로 수집될 수 있으며, 가비지 수집기는 광범위하게 연구되고 개발되어 왔다. 의미적 가비지는 일반적으로 자동으로 수집될 수 없으며, 따라서 가비지 수집 언어에서도 메모리 누수를 유발한다. 의미적 가비지를 감지하고 제거하는 것은 일반적으로 힙 프로파일러라는 특수한 디버깅 도구를 사용하여 수행되며, 이를 통해 어떤 객체가 활성 상태이고 어떻게 접근 가능한지 확인하여 의도하지 않은 참조를 제거할 수 있다.

5. 1. 가비지 수집의 장점

가비지는 힙 메모리를 소비하므로 메모리 사용을 최소화하고, 더 빠른 메모리 할당을 허용하며, 힙 조각화 및 메모리 사용 감소를 통해 메모리 부족 오류를 방지하기 위해 가비지를 수집하려 한다. 그러나 가비지 수집에는 시간이 걸리며, 수동으로 수행할 경우 코딩 오버헤드가 필요하다. 또한, 가비지 수집은 객체를 파괴하므로 파이널라이저 호출을 발생시킬 수 있으며, 프로그램 실행 중 임의의 지점에서 잠재적으로 임의의 코드를 실행한다.

5. 2. 가비지 수집의 단점

가비지 수집은 힙 메모리를 소비하므로 메모리 사용을 최소화하고, 더 빠른 메모리 할당을 허용하며, 힙 조각화 및 메모리 사용 감소를 통해 메모리 부족 오류를 방지하기 위해 수행된다. 그러나 가비지 수집에는 시간이 소요되며, 수동으로 수행할 경우 코딩 오버헤드가 필요하다. 또한, 가비지 수집은 객체를 파괴하므로 파이널라이저 호출을 발생시킬 수 있으며, 프로그램 실행 중 임의의 지점에서 잠재적으로 임의의 코드를 실행한다. 잘못된 가비지 수집은 메모리 안전 위반을 야기하며, 이는 댕글링 포인터의 사용 때문이다. 의미적 가비지는 일반적으로 자동으로 수집될 수 없으며, 따라서 가비지 수집 언어에서도 메모리 누수를 유발한다. 의미적 가비지를 감지하고 제거하는 것은 일반적으로 힙 프로파일러라는 특수한 디버깅 도구를 사용하여 수행된다.

6. 정보 보안과의 관계

참조

[1] 문서 近年では積極的に、ランダムあるいは何らかの変化するパターンを使い、バグの顕在化を図るようなシステムもある。
[2] 문서 これは構造的に、たとえば if - else if - が羅列されていた場合、最後の else で必ず初期化する、といったようになっている必要がある。



본 사이트는 AI가 위키백과와 뉴스 기사,정부 간행물,학술 논문등을 바탕으로 정보를 가공하여 제공하는 백과사전형 서비스입니다.
모든 문서는 AI에 의해 자동 생성되며, CC BY-SA 4.0 라이선스에 따라 이용할 수 있습니다.
하지만, 위키백과나 뉴스 기사 자체에 오류, 부정확한 정보, 또는 가짜 뉴스가 포함될 수 있으며, AI는 이러한 내용을 완벽하게 걸러내지 못할 수 있습니다.
따라서 제공되는 정보에 일부 오류나 편향이 있을 수 있으므로, 중요한 정보는 반드시 다른 출처를 통해 교차 검증하시기 바랍니다.

문의하기 : help@durumis.com