메모리 구조

이창민·2021년 12월 13일
0

CS

목록 보기
2/2

프로세스 메모리 구조


프로그램이 실행되면 OS는 메모리에 공간을 할당해준다.
할당되는 메모리 공간은 Text, Data, Heap, Stack이 있다.

Text

  • 프로그램 코드와 상수가 정의되어 있고,
    Read only이기 때문에 이 영역에 데이터를 저장하려 하면 분할 충돌을 일으켜 프로세스가 중지

Data

  • Data는 전역변수, 정적변수가 할당되는 공간이다. 프로그램이 실행될 때 생성되고 프로세스가 종료시 소멸
  • Data는 data영역과 bss영역으로 나뉜다.
    data영역에는 초기화 된 데이터가 저장되고 bss는 초기화 되지 않은 데이터가 저장
    • data를 data영역과 bss영역으로 나누는 이유 ?
      -> data영역에 저장되는 데이터는 ROM(비휘발성)에 저장되는데 비용이 많이 들어 RAM과 ROM에 저장될 것을 구분하기 위해 영역을 구분해 사용
      즉, 초기화되지 않은 데이터까지 ROM에 저장하면 낭비
      그러면 ROM은 Read only인데 어떻게 값을 수정하는가?
      -> 데이터 영역을 RAM에 복사해 런타임시 변경되는 값을 저장

Heap

  • 동적으로 메모리를 할당할 때 사용되는 영역
  • 메모리 주소 값에 의해 참조되고 사용되는 영역이다.
  • 런타임(프로그램 동작)시 크기 결정
  • C언어는 malloc, free로 사용자가 동적으로 관리하고 java의 경우 garbage collection이 관리
  • stack과 다르게 제한되지 않음
  • 메모리의 낮은 주소 -> 높은 주소로 할당

Stack

  • 잠시 사용됐다 사라지는(임시) 데이터 저장 영역
    • 즉, 함수 호출 시 생성되는 지역변수와 매개변수가 저장됨
    • 함수 호출시 할당(스택 push)되고 함수가 끝나면 메모리에서 해제(스택 pop)
    • 스택 영역에 저장된 함수 호출 정보를 StackFrame
  • 컴파일시 크기 결정
  • 스택의 크기는 OS에 따라 다르게 제한됨
  • 메모리의 높은 주소 -> 낮은 주소로 할당

Stack vs Heap

  • Stack과 Heap은 같은 메모리 공간을 사용
    • Stack 영역이 높은 주소 -> 낮은 주소로 할당 / Heap 영역이 낮은 주소 -> 높은 주소로 할당되기 때문에 Stack 사이즈가 클 수록 Heap의 사이즈가 줄고, 반대로 Heap이 클 수록 Stack이 작음
      • 스택과 힙이 서로의 영역을 침범하는 경우 각각 스택 오버플로우, 힙 오버플로우
  • 속도
    • Stack은 Heap보다 빠른 access
      • Stack은 컴파일 시 이미 할당된 공간을 사용해 스택 포인터의 위치만 바꿔줌
        (CPU에서 효율적으로 관리 -> 메모리 단편화 x)
      • Heap은 사용자가 따로 할당해 사용
        -> 효율적인 공간 사용을 보장하지 못하면 메모리 단편화가 발생할 수 있음

JAVA memory 관리

Java Garbage Collector

C언어에서는 malloc, free 로 사용자가 직접 Heap의 메모리를 관리하지만
Java에선 Garbage Collector가 알아서 해준다.
아래 코드를 통해 알아보자

public class Main {
	public static void main(String[] args){
    	String a = "Hello"
    	a += "World!"
        System.out.println(a)
    ]

처음 a가 할당된 뒤 스택과 힙은 아래와 같다.

그 다음 코드인

a += "World!"

문자열 더하기 연산이 수행되는 과정에서, 기존에 있던 Hello에 World!를 덧붙이는 것이 아니라, 문자열에 대한 더하기 연산이 수행된 결과가 새롭게 heap 영역에 할당된다. 이는 아래와 같다.

Stack에 새로운 변수가 할당되지 않고 문자열 더하기 연산의 결과가 새롭게 Heap 영역에 생성되는 것을 알 수 있다. 기존 Hello 를 레퍼런스 하는 a 변수는 새로 생성된 문자열을 레퍼런스한다.

그렇다면, 기존에 있던 Hello 문자열은 어떻게 되는가?
해당 문자열을 레퍼런스하는 변수가 없기 때문에 Unreachable 오브젝트가 된다.

JVM의 Garbage Collector는 Unreachable Object를 우선적으로 메모리에서 제거한다.
그렇다면 해당 모습은 아래와 같을 것이다.

참고자료

https://velog.io/@cchloe2311/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4-%EB%A9%94%EB%AA%A8%EB%A6%AC-%EA%B5%AC%EC%A1%B0
https://velog.io/@koyo/development-common-sense-1
https://velog.io/@goserimgoserimgo/%EB%A9%94%EB%AA%A8%EB%A6%AC-%EA%B5%AC%EC%A1%B0
https://yaboong.github.io/java/2018/05/26/java-memory-management/

profile
android 를 공부해보아요

0개의 댓글