CS

메모리(Memory)란? - 메모리를 제어하는 개발자

건우(gunoo) 2023. 5. 8. 03:28

1. 메모리가 부족해요

[JS]

  • "Out of memory: process ran out of memory"
  • "RangeError: out of memory"

[SWIFT]

  • "Fatal error: Out of memory"
  • "Thread 1: EXC_RESOURCE RESOURCE_TYPE_MEMORY (limit=XX MB, unused=0x0)"

[JAVA / KOTLIN]

  • "java.lang.OutOfMemoryError: Java heap space"
  • "java.lang.OutOfMemoryError: GC overhead limit exceeded"

개발자들에게 "메모리가 부족" 하다는 문제는 친숙하게 느껴진다.

-. 위와 같은 에러메세지로 만나본적도 있고,

-. 유저들로 부터 "로딩이 너무 느려요" 와 같은 문제로 만나본적도 있으며,

-. 어떠한 에러에 대해 "메모리 부족인가?" 와 같은 원인을 추측해보기도 한다.

 

[메모리] 부족의 문제를 나는 구체적으로 어떻게 해결했는지 생각해보면, 물론 정확하게 원인을 찾아 수정한 경우도 있었지만, 시간이 흘렀거나, 재부팅, 앱을 껏다 키는 행위 등을 통해 문제가 해결되어 버린 경우도 많은 것 같다.

 

메모리를 정확하게 알고 조작하는 레벨로 오르기를 바라며, [메모리]에 대한 지식을 정리해보려고 한다.

 

2.  컴퓨터의 작업 방식

1) CPU 와 Memory 의 협업

컴퓨터가 작동하는 방식을 간략하게 표현하자면, 외부에서 들어오는 다양한  입력값(Input) CPU가 처리하여 출력(Output)하는 방식이다.

위의 문장을 도식화하면 아래와 같이 나타낼 수 있다.

불완전한 작동

 

CPU가 처리하는 것 중 대표적인 2가지로 [Control Unit] 과 [Logic Unit]이 있다.

[Control Unit] 은 정보처리 역할로, 명령어들을 읽고 해석하며 데이터 처리에 대한 순서를 결정한다.

[Logic Unit] 은 계산 또는 연산을 처리하는 역할을 담당한다.

 

명령어들을 [Control Unit]이 해석하고, 순서를 결정하여 [Logic Unit]을 통해 연산하여 결과를 출력 한다고 보면 된다.

 

그러나 위와 같이 CPU만 있으면 조금이라도 복잡한 로직은 처리할 수 없게된다.

어떻게 계산할지, 무엇을 계산하지를 CPU는 기억할 수 없기 때문이다.

 

예를 들어 아래와 같은 코드가 있다고 가정했을 때,

func setCase(a:Int) -> Bool {
    if(a === 0){
        return false
    }else{
        return true
    }
}

setCase(a:0)
//Swift

setCase 라는 함수를 기억하지 못하면 컴퓨터는 어떻게 계산해야 하는지 알 수 없어 해당 함수를 가진 명령어가 들어와도 처리할 수 없게 된다.

 

이를 도와주는 것이 [Memory]이며 컴퓨터는 완전한 작동을 위해 아래와 같이 구성된다.

완전한 작동

 

이제 이렇게 생각해볼 수 있을 것 같다.

개발자는 [Memory]에 어떤 방식으로 유저의 입력을 처리할지 저장하는 것이고, CPU는 이를 꺼내서 연산하고 출력하는 것이다.

3.  Memory의 종류

좋은 성능을 가지도록 한 개발은 CPU가 빠르게 메모리의 정보를 읽고 쓰도록(access) 하는 개발이라고 볼 수 있는것 같다.

CPU가 상황에 맞게 메모리에 access할 수 있도록 한다면 출력이 원활할 수 있을 것이다.

 

먼저 종류를 알아보자

1) RAM (Random Access Memory)

  • 컴퓨터 시스템에서 가장 일반적으로 사용되는 메모리 형태이다.
  • CPU가 데이터와 명령어에 빠르게 엑세스 할 수 있도록 정보를 저장한다.
  • 데이터를 읽고 쓰는 데에 높은 속도를 가지며, 임의로 엑세스 할 수 있다는 특징을 가지고 있다.
  • 전원이 꺼지면 저장된 데이터가 사라지는 휘발성 메모리이다.

2) ROM (Read-Only Memory)

  • 읽기 전용 메모리이다.
  • 시스템 초기화 및 부팅 프로세스와 관련된 기본적인 정보를 저장한다.
  • 전원이 꺼져도 데이터가 사라지지 않는 비휘발성 메모리이다.

3) Cache Memory

  • CPU와 메모리 사이에서 데이터와 명령어를 임시로 저장하는 고속 메모리 이다.
  • CPU가 반복적으로 엑세스하는 데이터를 미리 저장하여 엑세스 시간을 단축시키고 성능을 향상 시킬수 있다.
  • 하드웨어 수준에서 관리되는 메모리이다.

4) Virtual Memory

  • RAM용량을 넘어서는 프로그램 및 데이터를 처리하기 위한 기술이다.
  • 물리적인 메모리 제약을 극복하고 다중 프로그램 실행 및 성능 향상을 지원한다.

5) Flash Memory

  • 비휘발성 메모리로, 전원이 꺼져도 데이터가 저장된다.
  • 데이터를 영구적으로 저장할 수 있는 소형 반도체 기억장치이다.
  • 주로 휴대폰, 카메라, USB드라이브, SSD 등에서 사용된다.

메모리 종류와 각각의 특징을 간단하게 정리해 보았다.

이제 개발자가 활용할 수 있는 메모리는 어떤것이 있을까?

 

나는 iOS와 WEB 서비스를 개발하고 있어, 브라우저의 메모리는 추후 살펴보기로 하고 

 

네이티브 개발자가 다룰 수 있는 메모리를 분류해 보았다.

  • RAM
    • 생명주기 관리 ( 메모리 누수 방지 / 메모리 사용 최적화 )
    • 리소스 관리 (이미지, 동영상 등)
    • 캐싱 ( 자주 사용되는 데이터, 중복 계산 결과를 캐싱하여 로딩 속도 최소화 )
    • 비동기 처리
    • 메모리 프로파일 (메모리 누수, 사용량 분석)
  • Virtual Memory
    • Java, Kotlin 안드로이드 제어 가능
    • Swift iOS 제어 불가능
  • Flash Memory
    • File System
    • Storage Access Framework [AOS] 
    • 데이터베이스
      • SQLite
      • [iOS] UserDefaults, CoreData
      • [aOS] SharedPreferences

4. 정리

가장 중요한것은 CPU가 빠르게 메모리에 엑세스 할 수 있도록 하는 것이다.

내가 다루는 기술이 접근할 수 있는 메모리의 종류와 특성을 알았으니, 이제 상황에 맞춰 어떻게 CPU가 메모리에 빠르게 접근 할 수 있도록 할지 설계하면 된다.

어떤 상황에 어떤 메모리에 접근해야 하는지 특징과 용어를 알게 되었으니, 메모리에 접근하여 제어하는 명령어들은 검색하면 된다.

 

큰 틀에 대해서 알아보았으니, 점점 더 깊게 알아보고 정리하려고 한다.

RAM은 개발을 하면서 일반적으로 가장 많이 제어하는 메모리인 만큼 RAM에 대한 정보를 더 알아보는 방향으로 정하였다.