programing

스택 가비지가 Java에서 수집됩니까?

procenter 2021. 1. 14. 23:21
반응형

스택 가비지가 Java에서 수집됩니까?


힙 메모리는 Java에서 가비지 수집됩니다.

스택 가비지도 수집됩니까?

스택 메모리는 어떻게 회수됩니까?


스택의 메모리에는 메서드 매개 변수와 지역 변수가 포함되어 있습니다 (정확히 말하자면 기본 유형에 대한 객체 및 변수 자체에 대한 참조). 메서드에서 나가면 자동으로 제거됩니다. 변수가 개체에 대한 참조 인 경우 개체 자체는 힙에 있으며 가비지 수집기에 의해 처리됩니다.

따라서 스택은 힙과 같은 방식으로 가비지 수집되지 않지만 스택은 자체적으로 자동 메모리 관리의 한 형태입니다 (가비지 수집 이전).

더 자세한 대답은 토마스 Pornin에 의해 제공됩니다 , 자세한 내용은이 조사.


스택은 Java에서 가비지 수집되지 않습니다.

지정된 메서드 호출에 할당 된 스택은 메서드가 반환 될 때 해제됩니다. 매우 간단한 LIFO 구조이기 때문에 가비지 수집이 필요하지 않습니다.

스택과 가비지 컬렉션이 상호 작용하는 한 곳은 스택의 참조가 GC 루트라는 것입니다 (즉, 도달 가능성이 결정되는 루트 참조임을 의미합니다).


스택 가비지 수집 될 있습니다. 그러나 대부분의 JVM 구현에서는 정의상 가비지 콜렉션을 배제하는 "스택"으로 처리됩니다.

우리가 스택이라고 부르는 것은 메서드 활성화 컨텍스트 의 축적입니다 . 호출 된 각 메서드에 대해 메서드 인수, 지역 변수, 호출 메서드의 컨텍스트에 대한 숨겨진 포인터 및 명령어를 저장하는 슬롯을 포함하는 개념적 구조입니다. 바늘. 활성화 컨텍스트는 Java 언어 자체에서 액세스 할 수 없습니다. 메서드가 종료되면 컨텍스트는 쓸모 없게됩니다.return또는 throw 된 예외로 인해). 메서드 A가 메서드 B를 호출 할 때 A가 제어권을 되 찾으면 B에 대한 컨텍스트가 쓸모 없게됩니다. 이것은 B에 대한 컨텍스트의 수명이 A에 대한 컨텍스트의 수명의 하위 범위임을 의미합니다. 따라서 활성화 컨텍스트 (주어진 스레드에 대한)는 LIFO ( "Last In, First Out") 규율로 할당 될 수 있습니다. 간단히 말해서 스택 : 새 활성화 컨텍스트가 컨텍스트 스택 맨 위에 푸시되고 맨 위에있는 컨텍스트가 가장 먼저 삭제됩니다.

실제로 활성화 컨텍스트 ( 스택 프레임 이라고도 함 )는 전용 영역에서 스택 순서로 연결됩니다. 이 영역은 스레드가 시작될 때 운영 체제에서 가져오고, 스레드가 종료되면 운영 체제가 다시 가져옵니다. 스택의 맨 위는 CPU 레지스터에 포함 된 특정 포인터로 지정됩니다 (JVM이 코드를 해석하거나 컴파일하는지 여부에 따라 다름). "발신자의 컨텍스트에 대한 포인터"는 가상입니다. 호출자의 컨텍스트는 반드시 스택 순서에서 바로 아래에 있습니다. GC는 개입하지 않습니다. 스택 영역은 스레드 활동 자체에서 동 기적으로 생성되고 회수됩니다. 이것은 또한 GC가 전혀없는 C 와 같은 많은 언어에서 작동하는 방식이기도합니다 .

이제 JVM 구현이 다른 작업을 수행하는 것을 막을 수있는 것은 없습니다. 예를 들어 힙에 활성화 컨텍스트를 할당하고이를 GC에서 수집하도록합니다. 스택 할당이 더 빠르기 때문에 일반적으로 Java Virtual Machines에서는 수행되지 않습니다. 그러나 일부 다른 언어는 이러한 작업을 수행해야합니다. 특히 GC (예 : Scheme 및 그 기능)를 사용하면서 연속으로 재생하는 언어는 이러한 게임이 위에서 설명한 LIFO 규칙을 위반하기 때문입니다.call-with-current-continuation


메모리의 스택 부분은 "스택"처럼 작동합니다. 나는 그것이 나쁘게 들리는 것을 알고 있지만 그것이 정확히 작동하는 방식입니다. 데이터는 상단에 추가되고 pushed onto the stack( popped off the stack) 프로그램이 실행 되면 상단 ( ) 에서 자동으로 제거 됩니다. 가비지 수집되지 않으며 데이터가 스택에서 튀어 나오면 해당 메모리가 자동으로 회수되기 때문에 그럴 필요가 없습니다. 그리고 내가 reclaimed라고 말할 때 할당 해제된다는 의미는 아닙니다. 데이터가 튀어 나옴에 따라 다음 데이터가 저장 될 스택 메모리의 위치가 감소한다는 것입니다.

물론 스택에 대해 전혀 걱정할 필요가 없다는 말은 아닙니다. 재귀 함수를 여러 번 실행하면 결국 모든 스택 공간을 사용하게됩니다. 많은 함수를 호출하는 경우, 특히 매개 변수 및 / 또는 지역 변수가 많은 경우 동일합니다.

그러나 결론은 함수가 범위를 자동으로 들어오고 나갈 때 스택의 메모리가 사용되고 회수된다는 것입니다. 따라서 프로그램 실행이 끝나면 모든 스택 메모리가 비워진 다음 운영 체제로 다시 릴리스됩니다.


스택에서 사용 된 메모리를 참조하면 가비지 수집되지 않습니다.
자바 가상 머신은 명시적인 바이트 코드 명령어를 사용하여 스택의 메모리를 예약하고 해제합니다. 이러한 명령어는 컴파일러에 의해 생성되며 스택의 int, boolean, double 및 객체 참조와 같은 기본 요소의 수명을 관리합니다.
더 이상 사용되지 않는다는 것이 알려지면 스택에서 일부 항목을 제거하는 소위 꼬리 호출 최적화를 구현할 계획이 있었지만 이미 이것을 지원하는 jvm을 모릅니다.
따라서 스택 자체에 대한 가비지 수집이 없으며 컴파일러 만 메모리 사용을 관리하기 위해 푸시 및 팝 명령을 생성했습니다.

스택 자체는 스레드의 일부입니다. 스택은 스레드 개체가 생성 될 때 할당되고 스레드가 종료되고 스레드 개체가 더 이상 참조되지 않은 후 가비지 수집됩니다.


Java의 모든 개체는 힙에 할당됩니다. (적어도 사양이 진행되는 한 실제 구현에서는 힙에있는 것처럼 투명하게 동작하는 경우 스택에 할당 할 수 있습니다.)

정확히 수집 가능한 것은 약간 미묘합니다. 객체에 대한 유일한 참조가 단일 스택 프레임에 있고 참조가 다시 사용되지 않음을 표시 할 수있는 경우 객체를 수집 할 수 있습니다. 개체가 필드를 읽는 데만 사용되는 경우 해당 필드 읽기는 앞으로 최적화되고 예상보다 일찍 개체가 수집 될 수 있습니다.

파이널 라이저 (또는 아마도 References)를 사용하지 않는 한 이것은 일반적으로 중요하지 않습니다 . 이 경우 조심하고 잠금 / 휘발성을 사용하여 happens-before관계 를 강화해야합니다 .

스레드가 중지되면 일반적으로 전체 스택이 할당 해제됩니다.


스택에있는 모든 것은 가비지 수집기에 의해 전역 루트로 처리됩니다. 그래, 당신은 확실히 스택이 "쓰레기 수집"이라고 말할 수 있습니다.


아무도, 데이터가 스택에서 푸시되고 팝되는 이유는 메소드 호출 중에 메소드에 내부 변수가 있기 때문입니다. 이것에 대해 신경 쓸 필요가 없습니다.


아니요. 스택은 Java에서 가비지 수집되지 않습니다. 각 스레드에는 자체 스택이 있으며 다음을 포함합니다.

  1. 방법 별 값 (짧은 수명) 및
  2. 힙에서 생성되고 메서드에서 참조되는 객체에 대한 참조

이러한 값은 모든 메서드 호출에 대해 스택 프레임으로 스택에 푸시됩니다. 스택은 'Last-in First-out'순서를 따르기 때문에 모든 메서드 호출이 끝날 때 모든 메서드 특정 데이터와 개체에 대한 참조 (있는 경우)를 포함하는 각 스택 프레임이 팝업됩니다.

따라서 스택의 데이터는 메서드 / 프로그램이 범위를 벗어나면 자동으로 정리됩니다.

참조 URL : https://stackoverflow.com/questions/2447504/is-the-stack-garbage-collected-in-java

반응형