Back-end

[Java] 자바 레퍼런스(Reference) - 스택과 힙

somuxsomu 2023. 12. 8. 18:34

 

자바(Java) 레퍼런스(Reference)

: 변수선언,  스택(Stack)과 힙(Heap)

 

 

오늘은 자바의 레퍼런스에 대해 정리를 해보았다.

변수선언 스택 그리고 힙에 대해서 알아보자.

 


 

자바 프로그램은 JVM(Java Virtual Machine -  자바 가상 머신)

이라는 프로그램이 실행시켜주는데,

 

IDE(편집기)에서 프로그램 실행 버튼을 누를 때 마다

IDE는 JVM을 실행시키고

JVM은 작성한 파일을 실행해 달라고 요청을 한다.

 

 

정확하게 말하면,

javac가 자바코드를 자바 바이트 코드로 바꾸고 

JVM이 해당 자바 바이트 코드를 실행 시킨다 !

 

 

JVM은 프로그램을 실행시키기 위해 여러가지 일을 하는데,

그 중 하나가 '메모리 관리'이다.

 

여기서 말하는 메모리는 RAM을 말한다.

 

 

"메모리는 한정적이기 때문에, 무한히 사용 할 수가 없다."

 

 

 

위의 코드와 같이 변수를 선언하는것,

 

오브젝트를 '생성'하는 것

바로 JVM에게 '나 메모리가 필요하니까 이 문법대로 알아서 너가 생성 해줘!'

라고 말하는것과 같다고 생각하면 된다.

 

위 코드가 실행되는 순간

JVM이 알아서 얼마만큼의 공간을 할당해야하는지,

어디에 할당해야하는지 계산을 하고 할당 해 준다.

 

그리고 우리는 필요가 없어지면, 사용하던 메모리 공간을 놓아줘야하는데

이 작업은 GrabageCollection이 해준다.

 

 

JVM은 한 프로그램이 실행시 

사용할 수 있는 전체 메모리를 목적에 따라 여러개의 다른 공간으로 나눈다.

그 중 하나가 스택(Stack)힙(Heap)이다.

 

 

스택(Stack)이라는 메모리는 메서드를 실행시키기 위해 사용한다.

예를들어, 메서드 내에서 변수를 선언하면 이 변수는 스택에 공간이 만들어진다.

 

힙(Heap) 은 오브젝트가 사는 공간이다. 

new 키워드를 이용해서 새 오브젝트를 만들어 달라고 하면 JVM은 힙이라는 공간에 만든다.

 

 

 

 

 

 

위 코드 처럼 thisIsString을 선언하면 (변수 선언)

 

JVM이 스택에 자리를 만들고 '이제부터 여기는 thisIsStirng이 쓸거야.' 라고 전한다. 

그럼, 메모리의 abc 라는 주소 번지의 공간은 thisIsString이 사용한다는 뜻이다.

 

위 코드 처럼, 

변수 선언만 하면 thisIsString에는 아무것도 들어있지 않다. 

변수에 아무것도 할당이 되지 않았을 때, '해당 변수의 값은 NULL이다.' 라고 한다.

 

NULL은 아무것도 없음을 의미한다.

 

그러므로,

현재 thisIsStirngNULL이다.

 

 

 

 

 

thisIsString에 new를 해주면(새 오브젝트 생성)

 

JVM은 힙의 어떠한 공간에 String 오브젝트를 생성한다. 

 

하지만,

아직 thisIsString과 새로 생성된 String 오브젝트 사이에는 

어떠한 관계도 없기 때문에 thisIsString은 NULL이다.

 

thisIsString에 할당을 해주면 NULL이 아닌,  

값이 생긴다.

 

 

 

 

 

위 코드처럼 ' = ' 을 사용해 thisIsStirng에 값을 할당해주면

 

thisIsStirng에 새로 만든 오브젝트가 들어있는 주소를 넣어준다.

이 주소를 자바에서는 '레퍼런스(Reference)'라고 부른다!

 

 

thisIsStirng를 사용할 때 마다,

JVM은 thisIsStirng의 주소를 보고

abc 라는 주소를 찾아가서 

코드에 입력된 대로 실행을 시켜준다!

 

 

그리고, 

자료형에 따라 스택에 선언된 변수에 주소가 들어갈 수도 있고, 값이 들어갈 수도 있다.

 

int, double 등 기본 자료형은 보통 숫자가 바로 들어가고

 

기본자료형들은 차지하는 메모리가 작기 때문이다.

 

new 키워드로 오브젝트를 생성해야 하는것들은 주소가 들어간다 !

 

 

 

 

 

마지막으로,

 

위 코드를 살펴보면

 

testDao.selectTestInfo 조회해온 값을 testInfo에 넣어 주고

그 값을 returnMap에 put 해주고

다시 testInfo에서 regUserName을 가져와서,

복호화를 해주고

다시 testInfo에 set을 해주고 난 후 returnMap을 return 해준다.

 

 

returnMap에 들어있는 키와 값을 확인해보면

복호화 해주기전 암호화된 이름이 아닌,

복호화가 된 이름이 들어가 있는데

 

이유는 위에서 설명을 생각해보면 된다!

 

 

Object는 실제 값이 들어가는게 아니고, 주소 값(래퍼런스 값)이 들어가기 때문에 이건 바뀌지 않고

대신 래퍼런스가 가르키는 공간에 들어있는 값이 .Set 하면 바뀐다 !

맵(testInfo)은 계속 같은 래퍼런스를 가르키고 있다.

 

 

testInfo를 returnMap에 put을 하고 

그 이후에 testInfo 값을 바꿔도

 

 

returnMap에는 바뀐 testInfo 값이 들어가 있다 !

 

😎