Java 쓰레기 수거 메커니즘 상세 및 실례 코드

3566 단어 Java쓰레기 수거
Java 쓰레기 수거 메커니즘 상세 정보
언뜻 보기에 쓰레기 회수가 하는 일은 그 이름과 꼭 맞아야 한다. 쓰레기를 찾아내고 제거해야 한다.사실은 정반대다.쓰레기 수거는 여전히 사용되고 있는 모든 대상을 추적하여 나머지 대상을 쓰레기로 표시한다.이 점을 명심하고 나서 쓰레기 수거라고 불리는 이 자동화 메모리 회수가 JVM에서 도대체 어떻게 실현되는지 깊이 있게 이해하겠습니다.
수동으로 메모리 관리
현대판 쓰레기 회수를 소개하기 전에 수동으로 메모리를 현저하게 분배하고 방출해야 했던 날들을 간단하게 되돌아본다.만약 네가 메모리를 방출하는 것을 잊었다면, 이 메모리는 다시 사용할 수 없을 것이다.이 메모리는 점유되었지만 사용되지 않았다.이런 장면은 메모리 유출이라고 불린다.
다음은 메모리를 수동으로 관리하는 C의 간단한 예입니다.

int send_request() {
  size_t n = read_size();
  int *elements = malloc(n * sizeof(int));

  if(read_elements(n, elements) < n) {
    // elements not freed!
    return -1;
  }

  // …

  free(elements)
  return 0;
}

메모리 방출을 잊어버리기 쉽다는 것을 알 수 있다.메모리 유출은 일찍이 매우 보편적인 문제였다.너는 끊임없이 자신의 코드를 복구함으로써 그것들과 항쟁할 수 있을 뿐이다.따라서 인위적인 오류 가능성을 줄이기 위해 쓸모없는 메모리를 자동으로 방출하는 더 우아한 방법이 필요하다.이런 자동화 과정은 쓰레기 회수라고도 부른다.
지능 지침
자동 쓰레기 회수 초기의 실현은 바로 인용 계수였다.너는 모든 대상이 몇 번이나 인용되었는지 알고 있다. 계수기가 0으로 돌아갈 때, 이 대상은 안전하게 회수될 수 있다.C++의 공유 포인터는 매우 유명한 예입니다.

int send_request() {
  size_t n = read_size();
  stared_ptr<vector<int>> elements 
       = make_shared<vector<int>&gt();

  if(read_elements(n, elements) < n) {
    return -1;
  }

  return 0;
}

우리가 사용하는sharedptr는 이 대상이 인용된 횟수를 기록합니다.만약 당신이 그것을 다른 사람에게 전달한다면 계수에 하나를 더하면, 그것이 작용역을 떠난 후에 하나를 줄일 것이다.이 계수가 0이면sharedptr는 자동으로 밑에 있는vector를 삭제합니다.물론 이것은 단지 예일 뿐이다. 왜냐하면 독자들이 지적하기 때문이다. 이것은 현실에서는 나타날 수 없지만 시범으로 충분하다.
자동 메모리 관리
위의 C++ 코드에서, 우리는 메모리 관리를 사용해야 한다는 것을 명확하게 설명해야 한다.만약 모든 대상이 이 메커니즘을 채택한다면 어떻게 될까요?그것은 정말 편리하다. 이렇게 하면 개발자는 메모리를 정리하는 일을 고려할 필요가 없다.실행할 때 어떤 메모리가 더 이상 사용되지 않는지 자동으로 알고 그것을 방출합니다.쓰레기를 자동으로 회수한 셈이다.1세대 쓰레기 수거기는 1959년 Lisp가 도입한 것으로 이 기술은 지금까지 끊임없이 발전해 왔다.
참조 개수
방금 우리가 C++의 공유 바늘로 보여준 생각은 모든 대상에 적용될 수 있다.많은 언어, 예를 들면 Perl, Python 및 PHP는 모두 이런 방식을 채택한다.이것은 한 장의 그림을 통해 쉽게 설명할 수 있다.
녹색 구름은 프로그램에서 여전히 사용되고 있는 대상을 대표한다.기술적인 측면에서 볼 때 이것은 마치 실행 중인 어떤 방법 중의 국부 변수나 정적 변수 같은 것이다.서로 다른 프로그래밍 언어의 상황은 다를 수 있기 때문에 이것은 우리가 주목하는 중점이 아니다.
파란색 동그라미는 메모리의 대상을 대표하는데, 얼마나 많은 대상이 그것들을 인용했는지 볼 수 있다.회색 동그라미의 대상은 이미 아무도 인용하지 않았다.따라서 이들은 쓰레기 대상에 속해 쓰레기 수거기에 치울 수 있다.
괜찮은 것 같아요. 그렇죠?맞아요. 그런데 여기에 중대한 결함이 있어요.고립된 고리가 나타나기 쉬우며, 그 중의 대상은 그 어떠한 역내에도 없지만, 서로 인용하여 인용 수가 0이 되지 않는다.다음은 예입니다.
봤지, 빨간색 부분은 사실 응용 프로그램이 더 이상 사용하지 않는 쓰레기 대상이야.인용 계수의 결함으로 인해 메모리 유출이 발생할 수 있습니다.
특수한'약'인용을 사용하거나 특수한 알고리즘을 사용하여 순환 인용을 회수하는 몇 가지 방법이 있다.앞서 언급한 Perl,Python, PHP 등 언어는 모두 유사한 방법으로 순환 인용을 회수하지만 이것은 본고에서 설명한 범위를 넘어섰다.JVM이 채택하는 방법에 대해 자세히 설명할 예정입니다.
태그 삭제
먼저 JVM은 객체 가용성에 대한 정의를 명확하게 해야 합니다.이것은 앞처럼 녹색 구름으로 얼버무리는 것이 아니라 매우 명확하고 구체적인 쓰레기 수거 루트 대상(Garbage Collection Roots)의 정의를 가지고 있다.
  • 국부 변수
  • 활동 노선
  • 정적 필드
  • JNI 참조
  • 기타 (추후 논의 예정)
  • JVM은 삭제된 알고리즘을 표시하여 모든 도달 가능 (생존) 객체를 기록하고, 도달할 수 없는 객체의 메모리를 다시 사용할 수 있도록 합니다.여기에는 다음 두 단계가 포함됩니다.
  • 표시는 모든 도달할 수 있는 대상을 훑어보고 로컬 메모리에 이 대상의 정보를 기록하는 것을 말한다
  • 삭제하면 도달할 수 없는 대상의 메모리 주소가 다음 메모리 할당에서 사용할 수 있도록 합니다.
  • JVM의 서로 다른 GC 알고리즘, 예를 들어 Parallel Scavenge, Parallel Mark+Copy, CMS는 모두 이 알고리즘의 서로 다른 실현이다. 단지 각 단계가 약간 다를 뿐이다. 개념적으로 말하자면 여전히 위에서 말한 두 단계에 대응한다.
    이런 실현의 가장 중요한 것은 더 이상 누설된 대상 고리가 나타나지 않는 것이다.
    단점은 프로그램의 라인이 정지되어야 회수를 완성할 수 있다는 것이다. 인용이 계속 바뀌면 계수를 할 수 없다.이 응용 프로그램은 JVM이 집안일을 정리할 수 있도록 정지된 경우를 STW(Stop The World pause)라고도 부른다.이런 정지가 촉발될 가능성은 매우 많지만 쓰레기 회수는 가장 흔히 볼 수 있는 것이다.
    읽어주셔서 감사합니다. 여러분에게 도움이 되었으면 좋겠습니다. 본 사이트에 대한 지지에 감사드립니다!

    좋은 웹페이지 즐겨찾기