logo

스택과 힙 메모리 할당

C/C++/Java 프로그램의 메모리는 스택이나 힙에 할당될 수 있습니다.
전제 조건: C 프로그램의 메모리 레이아웃 .


스택 할당: 할당은 인접한 메모리 블록에서 발생합니다. 할당이 함수 호출 스택에서 발생하기 때문에 이를 스택 메모리 할당이라고 부릅니다. 할당될 메모리의 크기는 컴파일러에 알려져 있으며 함수가 호출될 때마다 해당 변수는 스택에 메모리를 할당받습니다. 그리고 함수 호출이 끝날 때마다 변수에 대한 메모리 할당이 해제됩니다. 이 모든 일은 컴파일러에서 미리 정의된 일부 루틴을 사용하여 발생합니다. 프로그래머는 스택 변수의 메모리 할당 및 할당 해제에 대해 걱정할 필요가 없습니다. 이러한 종류의 메모리 할당은 메서드 실행이 완료되자마자 해당 메서드에 속한 모든 데이터가 자동으로 스택에서 플러시되기 때문에 임시 메모리 할당이라고도 합니다. 이는 메서드가 실행을 완료하지 않았고 현재 실행 중인 상태인 한 스택 메모리 구성표에 저장된 모든 값에 액세스할 수 있음을 의미합니다.



자바 프로그래밍 배열

키 포인트:

  • 이는 해당 데이터 멤버를 포함하는 메서드( )가 현재 실행 중인 경우에만 데이터 멤버에 액세스할 수 있는 임시 메모리 할당 방식입니다.
  • 해당 메서드의 실행이 완료되는 즉시 자동으로 메모리를 할당하거나 할당 해제합니다.
  • 해당 오류 Java가 수신됩니다. 랭. 스택오버플로우오류 ~에 의해 JVM , 스택 메모리가 완전히 채워진 경우.
  • 스택 메모리 할당은 저장된 데이터가 소유자 스레드에서만 액세스할 수 있기 때문에 힙 메모리 할당에 비해 더 안전한 것으로 간주됩니다.
  • 힙 메모리 할당에 비해 메모리 할당 및 할당 해제가 더 빠릅니다.
  • 스택 메모리는 힙 메모리에 비해 저장 공간이 적습니다.
C++
int main() {  // All these variables get memory  // allocated on stack  int a;  int b[10];  int n = 20;  int c[n]; }>


힙 할당: 프로그래머가 작성한 명령을 실행하는 동안 메모리가 할당됩니다. 힙이라는 이름은 힙과 아무 관련이 없습니다. 메모리 누수 프로그램에서 발생할 수 있습니다.

힙 메모리 할당은 세 가지 범주로 더 나뉩니다. 이 세 가지 범주는 힙 메모리 또는 힙 메모리에 저장될 데이터(객체)의 우선 순위를 지정하는 데 도움이 됩니다. 쓰레기 수거 .

안드로이드 유튜브에서 광고 차단하기
  • 젊은 세대 – 모든 새로운 데이터(객체)가 공간을 할당하기 위해 만들어지는 메모리 부분이며, 이 메모리가 완전히 채워질 때마다 나머지 데이터는 가비지 컬렉션에 저장됩니다.
  • 구세대 또는 종신세대 - 자주 사용하지 않거나 전혀 사용하지 않는 오래된 데이터 객체를 포함하는 힙 메모리의 일부입니다.
  • 영구 세대 - 이는 런타임 클래스 및 애플리케이션 메소드에 대한 JVM의 메타데이터를 포함하는 힙 메모리의 일부입니다.

키 포인트:

  • 힙 공간이 완전히 가득 차면 해당 오류 메시지가 표시됩니다. 자바. lang.OutOfMemoryError JVM으로.
  • 이 메모리 할당 방식은 스택 공간 할당과 다르며 여기서는 자동 할당 해제 기능이 제공되지 않습니다. 메모리를 효율적으로 사용하려면 가비지 컬렉터를 사용하여 사용하지 않는 오래된 객체를 제거해야 합니다.
  • 이 메모리의 처리 시간(액세스 시간)은 스택 메모리에 비해 상당히 느립니다.
  • 힙 메모리에 저장된 데이터는 모든 스레드에서 볼 수 있으므로 힙 메모리는 스택 메모리만큼 스레드로부터 안전하지 않습니다.
  • 힙 메모리의 크기는 스택 메모리에 비해 상당히 큽니다.
  • 힙 메모리는 전체 애플리케이션(또는 Java 프로그램)이 실행되는 동안 액세스 가능하거나 존재합니다.
CPP
int main() {  // This memory for 10 integers  // is allocated on heap.  int *ptr = new int[10]; }>

Java에서 두 종류의 메모리 할당 힙과 스택이 혼합된 예:

C++
#include  using namespace std; int main() {  int a = 10; // stored in stack  int* p = new int(); // allocate memory in heap  *p = 10;  delete (p);  p = new int[4]; // array in heap allocation  delete[] p;  p = NULL; // free heap  return 0; }>
자바
class Emp {  int id;  String emp_name;  public Emp(int id, String emp_name) {  this.id = id;  this.emp_name = emp_name;  } } public class Emp_detail {  private static Emp Emp_detail(int id, String emp_name) {  return new Emp(id, emp_name);  }  public static void main(String[] args) {  int id = 21;  String name = 'Maddy';  Emp person_ = null;  person_ = Emp_detail(id, name);  } }>
파이썬
def main(): a = 10 # stored in stack p = None # declaring p variable p = 10 # allocating memory in heap del p # deleting memory allocation in heap p = [None] * 4 # array in heap allocation p = None # free heap return 0 if __name__ == '__main__': main()>
자바스크립트
// Define the Emp class with id and emp_name properties class Emp {  constructor(id, emp_name) {  this.id = id; // Initialize id  this.emp_name = emp_name; // Initialize emp_name  } } // Create an instance of the Emp class const person = new Emp(21, 'Maddy'); // Initialize person with id 21 and emp_name 'Maddy' console.log(person); // Output the person object to the console>

위의 예를 분석한 후 우리가 내릴 결론은 다음과 같습니다.

자바의 버블 정렬
  • have 프로그램의 실행을 시작하면 모든 런타임 클래스가 힙 메모리 공간에 저장됩니다.
  • 그런 다음 다음 줄에서 모든 기본(또는 로컬)과 함께 스택에 저장되는 main() 메서드를 찾고 Emp_detail 유형의 참조 변수 Emp도 스택에 저장되어 해당 개체를 가리킵니다. 힙 메모리에 저장됩니다.
  • 그런 다음 다음 줄에서는 main()에서 매개변수화된 생성자 Emp(int, String)를 호출하고 동일한 스택 메모리 블록의 맨 위에도 할당합니다. 여기에는 다음이 저장됩니다.
    • 스택 메모리의 호출된 개체에 대한 개체 참조입니다.
    • 기본 값( String emp_name 인수의 참조 변수는 문자열 풀의 실제 문자열을 힙 메모리로 가리킵니다.
  • 그런 다음 기본 메서드는 Emp_detail() 정적 메서드를 다시 호출하여 이전 메모리 블록 위에 있는 스택 메모리 블록에 할당이 이루어집니다.
  • String emp_name 인수의 참조 변수는 문자열 풀의 실제 문자열을 힙 메모리로 가리킵니다.
  • 따라서 Emp_detail 유형의 새로 생성된 객체 Emp의 경우 모든 인스턴스 변수가 힙 메모리에 저장됩니다.
  • String emp_name 인수의 참조 변수는 문자열 풀의 실제 문자열을 힙 메모리로 가리킵니다.

  • 아래 그림 1과 같은 그림 표현:

    String emp_name 인수의 참조 변수는 문자열 풀의 실제 문자열을 힙 메모리로 가리킵니다.
  • 그림 1

    스택 할당과 힙 할당의 주요 차이점

    1. 스택에서는 할당 및 할당 해제가 컴파일러에 의해 자동으로 수행되는 반면, 힙에서는 프로그래머가 수동으로 수행해야 합니다.
    2. 힙 프레임을 처리하는 것은 스택 프레임을 처리하는 것보다 비용이 더 많이 듭니다.
    3. 메모리 부족 문제는 스택에서 발생할 가능성이 더 높지만 힙 메모리의 주요 문제는 조각화입니다.
    4. 스택은 메모리 영역이 작고 캐시 친화적이므로 스택 프레임 액세스는 힙 프레임보다 쉽지만, 메모리 전체에 분산되어 있는 힙 프레임의 경우 더 많은 캐시 누락이 발생합니다.
    5. 스택은 유연하지 않고 할당된 메모리 크기를 변경할 수 없지만 힙은 유연하며 할당된 메모리를 변경할 수 있습니다.
    6. 힙 소요 시간에 액세스하는 것은 스택 이상입니다.

    비교 차트

    매개변수스택더미
    기초적인메모리는 연속된 블록에 할당됩니다.메모리는 임의의 순서로 할당됩니다.
    할당 및 할당 취소컴파일러 지침에 따라 자동으로 수행됩니다.프로그래머가 수동으로 작성합니다.
    비용더 적은
    구현쉬운딱딱한
    액세스 시간더 빠르게느리게
    주요 문제메모리 부족메모리 조각화
    참조 지역성훌륭한적절한
    안전스레드 안전, 저장된 데이터는 소유자만 액세스할 수 있습니다.스레드로부터 안전하지 않음, 저장된 데이터는 모든 스레드에 표시됨
    유연성고정 크기크기 조정이 가능합니다
    데이터 유형 구조선의계층적
    우선의배열에서는 정적 메모리 할당이 선호됩니다.연결된 목록에서는 힙 메모리 할당이 선호됩니다.
    크기힙 메모리보다 작습니다.스택 메모리보다 큽니다.