CodeGym /행동 /JAVA 25 SELF /메모리 주소 지정과 변수

메모리 주소 지정과 변수

JAVA 25 SELF
레벨 2, 레슨 4
사용 가능

1. 메모리의 구조

모든 컴퓨터에는 주기억장치(RAM)가 있습니다. 그것이 무엇이며 어떤 특성을 가지고 있는지, 그리고 가장 중요한 것은 우리에게 어떤 이점이 있는지 알아봅시다.

각 프로그램(그리고 Java로 작성된 프로그램도 포함)은 실행 전에 RAM에 적재됩니다. RAM에는 프로그램 코드(프로세서가 실행하는 코드)와 프로그램 데이터(프로그램이 메모리에 적재하는 데이터)가 들어 있습니다.

그렇다면 RAM은 무엇이며 무엇에 비유할 수 있을까요?

Excel을 떠올려 보세요 😎 Excel의 시트는 셀들로 이루어져 있고, 각 셀은 고유한 번호를 가집니다(A1, A2, ... B1, B2). 셀 번호를 알면 언제든 그 셀에 값을 기록하거나 그곳에 저장된 값을 읽을 수 있습니다. 컴퓨터 메모리도 비슷한 방식으로 구성됩니다.

memory-excel

프로그램과 그 데이터는 실행 중에 메모리에 저장됩니다. 컴퓨터의 전체 메모리는 작은 셀, 즉 바이트들의 형태로 표현됩니다. 각 셀에는 고유한 번호가 있습니다 — 0, 1, 2, 3, ...(번호는 0부터 시작). 셀 번호를 알고 있으면 그 셀에 데이터를 저장할 수도 있고, 꺼낼 수도 있습니다. 어떤 셀에는 프로그램 코드(프로세서용 명령 집합)가, 다른 셀에는 그 프로그램의 데이터가 저장됩니다. 셀의 번호는 셀의 주소라고도 부릅니다.

프로세서는 메모리에 적재된 프로그램의 명령을 실행할 수 있습니다. 거의 모든 프로세서 명령은 다음과 같은 형태입니다: 몇몇 셀에서 데이터를 가져온다 → 그 데이터로 무언가를 수행한다 → 결과를 다른 셀에 저장한다.

수백 개의 간단한 명령을 결합하면 복잡하고 유용한 동작을 만들 수 있습니다.

프로그램 코드에서 변수를 선언하면 아직 사용되지 않은 메모리의 일부분이 그 변수에 할당됩니다. 보통 몇 바이트입니다. 변수를 선언할 때는 그 변수에 저장할 정보의 타입(숫자, 텍스트 또는 기타 데이터)을 반드시 지정해야 합니다. 타입을 알아야 변수에 얼마나 큰 메모리 블록을 할당할지 결정할 수 있기 때문입니다.

컴퓨터 산업의 초창기에는 프로그램이 메모리 셀의 번호로 직접 작업했습니다. 하지만 이후 프로그래머의 편의를 위해 셀에 이름을 붙이기 시작했습니다. 변수의 고유한 이름은 무엇보다 프로그래머의 편의를 위한 것입니다. 프로그램은 실행 중에 번호만으로도 충분히 잘 작동합니다.

2. 메모리 속 변수

Java에는 정수를 저장하기 위한 기본 데이터 타입이 4가지 있습니다. byte, short, int, long입니다.

타입 크기(바이트) 이름의 유래
byte
1
Byte — 메모리 1바이트를 차지하기 때문
short
2
Short Integer의 약자
int
4
Integer의 약자
long
8
Long Integer의 약자

또한 Java에는 2개의 실수형 타입 — float와 double이 있습니다:

타입 크기(바이트) 이름의 유래
float
4
Floating Point Number의 약자
double
8
Double Float의 약자

프로그램 실행이 변수 생성 명령에 도달할 때마다, 그 변수 타입에 따라 작은 메모리 영역이 할당됩니다(크기는 변수 타입에 따라 다릅니다).

중요!

변수의 주소는 그 변수에 할당된 메모리 블록의 첫 번째 셀의 주소를 의미합니다.

Java 프로그램은 메모리에 직접 접근하는 것이 금지되어 있습니다. 메모리 작업은 모두 Java 가상 머신을 통해서만 이뤄집니다.

3. 메모리에서의 String 타입

String 타입은 큰 양의 데이터를 저장할 수 있으므로, 단순한 데이터 타입이 아니라 완전한 객체입니다.

String 타입의 실제 데이터(텍스트)는 별도의 객체에 저장되며, 그 객체에 메모리가 할당됩니다. 그리고 그 객체의 주소가 변수에 저장되는데, 이 변수 역시 메모리가 할당됩니다.

memory-string

  • int 타입의 변수 a는 4바이트를 차지하며 값 1을 저장합니다.
  • int 타입의 변수 b는 4바이트를 차지하며 값 10,555를 저장합니다. 여기서 쉼표는 소수 부분이 아니라 자릿수 구분입니다. 소수 부분은 점(.)으로 구분합니다.
  • double 타입의 변수 d는 8바이트를 차지하며 값 13.001을 저장합니다.
  • String 타입의 변수 str은 값 D12를 저장하는데, 이는 텍스트를 담은 객체의 첫 번째 셀 주소입니다.

객체인 String(텍스트 포함)은 별도의 메모리 블록에 저장됩니다. 그 첫 번째 셀의 주소가 변수 str에 저장됩니다.

4. 값을 대입할 때 무슨 일이 일어나는가

또 하나 중요한 점 — 대입이 어떻게 동작하는가입니다. 예를 들어:

int a = 10;
int b = a;
b = 20;
System.out.println(a); // 10

이 예에서는 메모리에 두 개의 셀이 생성됩니다: 하나는 a, 다른 하나는 b입니다. b = a;라고 쓰면 복사되는 것은 값(10)이지, “상자” 자체가 아닙니다. 따라서 b의 변경은 a에 아무런 영향을 주지 않습니다.

이제 문자열에서도 비슷한 예를 보겠습니다:

String s1 = "Hello";
String s2 = s1;
s2 = s2 + " World";
System.out.println(s1); // "Hello"
System.out.println(s2); // "Hello World"

여기서 두 변수 s1과 s2는 변경 전까지 같은 문자열 "Hello"를 가리킵니다. 하지만 s2 = s2 + " World";를 수행하면 s2를 위한 새로운 문자열 "Hello World"가 생성되고, s1은 여전히 기존 문자열 "Hello"를 참조합니다.

5. 프로그래밍에서 왜 모든 것을 0부터 번호 매기는가

많은 사람들이 프로그래밍에서 거의 모든 것이 왜 0부터 시작하는지 궁금해합니다. 이는 0부터 세는 것이 더 편리한 상황이 매우 많기 때문입니다(물론 1부터 세는 것이 더 편리한 경우도 있습니다).

비유를 들어 보겠습니다. 긴 줄에 서 있는데, 캐셔가 “20번째부터는 2번 카운터로 가세요”라고 말했습니다. 그러면 그 사람들의 번호는 무엇일까요? 20, 21, 22, 23, ...가 됩니다. 기준을 20번째로 잡으면 상대 번호는 0, 1, 2, 3, ...가 됩니다.

어떤 구간을 “첫 요소의 번호” + “개수”로 정의하면, 그 내부의 상대 인덱스는 +0, +1, +2, ...가 됩니다.

프로그래밍도 같습니다. 변수에 100바이트의 메모리가 할당되어 있고, X가 첫 바이트의 주소라면, 모든 바이트의 주소는 어떻게 될까요? X+0, X+1, X+2, ..., X+99입니다. 이렇게 해서 우리는 인덱스가 0, 1, 2, 99인 바이트들의 집합을 얻게 됩니다.

데이터 블록 내부의 상대 주소를 생각하면 항상 0부터 번호가 매겨집니다. 이것이 0부터 세는 가장 첫 번째이자 가장 흔한 이유입니다.

1
과제
JAVA 25 SELF, 레벨 2, 레슨 4
잠금
게임 캐릭터 프로필 🎮
게임 캐릭터 프로필 🎮
1
과제
JAVA 25 SELF, 레벨 2, 레슨 4
잠금
프로젝트 이름 복사 및 변경 📝
프로젝트 이름 복사 및 변경 📝
1
과제
JAVA 25 SELF, 레벨 2, 레슨 4
잠금
데이터 크기 📊
데이터 크기 📊
1
과제
JAVA 25 SELF, 레벨 2, 레슨 4
잠금
은행의 두 계좌 🏦
은행의 두 계좌 🏦
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION