Stack vs Heap
Stack은 메소드가 실행될 때 변수가 push(입력)되며 실행이 종료될 때 pop(해제)된다.
heap은 new혹은 c에서는 malloc 될 때 만들어지며 자바는 가비지 컬렉션에 의해 사용되지 않을 때 자동으로 해제되고, c에서는 직접 관리해서 해제 해줘야 한다.
스택
스택이란 무엇입니까? 이것은 각 기능 (기능 포함)에 의해 생성 된 임시 변수를 저장하는 컴퓨터 메모리의 특별한 영역입니다 main(). 스택은 "LIFO"(last in, first out) 데이터 구조로 CPU에 의해 관리되고 최적화됩니다. 함수가 새 변수를 선언 할 때마다 스택에 "푸시 (push)"됩니다. 그런 다음 함수가 종료 될 때마다 해당 함수에 의해 스택에 푸시 된 모든 변수가 해제됩니다 (즉, 삭제됩니다). 스택 변수가 해제되면 다른 스택 변수에서도 해당 메모리 영역을 사용할 수있게됩니다.
스택을 사용하여 변수를 저장하면 메모리가 관리된다는 이점이 있습니다. 메모리를 손으로 할당 할 필요가 없으며 더 이상 필요하지 않으면 메모리를 확보 할 필요가 없습니다. 게다가 CPU가 스택 메모리를 효율적으로 구성하기 때문에 스택 변수를 읽고 쓰는 속도가 매우 빠릅니다.
스택을 이해하는 핵심 은 함수가 종료 되면 모든 변수가 스택에서 팝 아웃된다는 것입니다 (따라서 영원히 손실됩니다). 따라서 스택 변수는 사실상 국부적 입니다. 이것은 앞서 가변 범위 또는 로컬 변수와 전역 변수 로 알려진 개념과 관련이 있습니다. C 프로그래밍의 일반적인 버그는 일부 함수 내부의 스택에서 생성 된 변수에 액세스하려고 시도하는 것입니다 (함수가 종료 된 후).
스택의 또 다른 특징은 스택에 저장할 수있는 변수의 크기에 제한이 있다는 것입니다 (OS에 따라 다름). 힙에 할당 된 변수의 경우는 그렇지 않습니다 .
스택을 요약하려면 다음을 수행하십시오.
함수가 푸시 (push) 및 팝 (pop) 로컬 변수로서 스택이 커지고 축소됩니다.
메모리를 직접 관리 할 필요가 없습니다. 변수는 자동으로 할당되고 해제됩니다.
스택에 크기 제한이있다.
스택 변수는 생성 된 함수가 실행되는 동안에 만 존재합니다.
힙
힙은 자동으로 관리되지 않고 CPU가 엄격하게 관리하지 않는 컴퓨터 메모리 영역입니다. 더 자유롭게 떠 다니는 메모리 영역입니다. 힙에 메모리를 할당하려면 malloc()or 을 사용해야하며 calloc(), 내장 C 함수입니다. 힙에 free()메모리 혹은 자바에서는 new를 하면 더 이상 필요하지 않은 메모리를 할당 해제해야합니다. 이렇게하지 않으면 프로그램에 메모리 누수가 발생 합니다. 즉, 힙의 메모리는 여전히 따로 설정됩니다 (다른 프로세스에서는 사용할 수 없습니다). 디버깅 섹션에서 볼 수 있듯이 valgrind 메모리 누수를 감지하는 데 도움 이되는 도구 가 있습니다. 하지만 자바는 가비지 컬렉션을 이용한다.
스택과 달리 힙에는 (컴퓨터의 명백한 물리적 한계를 제외하고) 가변 크기에 대한 크기 제한이 없습니다. 힙 메모리는 포인터 를 사용 하여 힙의 메모리에 액세스 해야하기 때문에 읽기와 쓰기가 약간 느립니다
스택과 달리 힙에 작성된 변수는 프로그램의 모든 함수에서 액세스 할 수 있습니다. 힙 변수는 본질적으로 범위가 전역입니다.
간단하게 말하면 변수의 범위는 아래와 같이 나뉩니다.
1. 지역변수 vs 전역변수
2. 지역변수에는 static변수라는게 없습니다. 이유는 스택(메소드 내부)안의 변수는 기본적으로 실행시에 메모리에 할당되고 static변수는 JVM실행시에 메모리에 바로 할당되어 JVM종료시 까지 메모리에 떠 있어야 하기 때문에 이론적으로 맞지 않습니다.
3. 지역변수에는 일반 변수만 존재할 수 있습니다.
4. 전역변수에는 static 전역변수와 heap 전역변수로 나뉩니다.
- 전역변수의 의미는 쉽게 말해 스택에 들어가지 않는 모든 변수를 말합니다.
- 전역변수 중 static이 붙어 있는 변수는 JVM실행시 부터 클래스 메모리에 할당됩니다.
- 전역변수 중 static이 붙어 있지 않는 변수는 동적으로 new 될때 heap에 할당됩니다.
5. heap변수는 new가 되고 난 뒤 부터 공유해서 사용가능합니다. static 변수는 처음부터 공유해서 사용가능합니다.
6. static 메소드 안에서 일반변수를 선언 및 초기화하는 것은 가능하지만 사용하는 것은 불가능합니다.
그 이유는 static메소드는 JVM실행시 클래스 메모리에 메소드의 주소가 뜹니다. 그 안에 내용은 static메소드가 실행될 때 push되게 되는데 객체가 생성되기 이전 시점에 static메소드가 실행되면 일반변수를 찾을 수가 없으니 당연히 사용하지 못합니다.
7. 일반 메소드 안에서 static변수를 선언하는 것은 불가능하지만 사용하는 것은 가능합니다.
그 이유는 일반 메소드가 실행되려면 기본적인 조건이 객체가 생성되어야 합니다. 그렇다면 객체가 생성되어야 실행될 수 있는 메소드 안에 static변수를 선언하는 것은 이론상 맞지 않습니다. 왜냐하면 static변수는 JVM실행시 바로 클래스 메모리에 할당되어야 하는데 일반 메소드는 누군가가 new를 해줘야 메모리에 뜨기 때문에 서로의 타이밍이 맞지 않는 것입니다.
결국 static변수가 일반 메소드 안에서 선언되어 버리면 일반메소드가 실행되기 전까지는 static변수가 선언될 수 가 없으니 JVM이 처음 실행될 때 static변수를 클래스 메모리에 할당할 수 없는 것입니다.
하지만 static변수를 사용하는 것은 가능합니다. 왜냐하면 객체가 생성되기 전시점이든 생성된 후 시점이든 static변수는 항상 떠 있기 때문에 언제든지 찾을 수 있기 때문입니다.
Stack vs Heap 장단점
스택
매우 빠른 액세스
변수를 명시 적으로 할당 해제 할 필요가 없습니다.
공간은 CPU에 의해 효율적으로 관리되고 메모리는 단편화되지 않습니다.
지역 변수 만
스택 크기 제한 (OS에 따라 다름)
변수의 크기를 조정할 수 없습니다.
힙
변수는 전역 적으로 액세스 할 수 있습니다.
메모리 크기 제한 없음
(상대적으로) 느린 액세스
효율적인 공간 사용을 보장하지 못하면 메모리 블록이 할당 된 후 시간이 지남에 따라 메모리가 조각화되어 해제 될 수 있습니다.
메모리를 관리해야합니다 (변수를 할당하고 해제하는 책임이 있습니다)
변수는 C언어 realloc() or 자바 new
'Programming > Java' 카테고리의 다른 글
우리말샘 API 2020. 06 .24 (0) | 2020.06.29 |
---|---|
국립국어원 API 2020. 06 .24 (0) | 2020.06.29 |
신문기사 자연어 처리 2020. 06 .24 (0) | 2020.06.29 |
JAVA 환경설정 (0) | 2020.03.13 |
JVM의 메모리모델 (0) | 2020.03.13 |