Javascript

String 값은 어디에 저장이 될까?

v8rus 2022. 12. 1. 10:22

이전에 JS의 배열에 대해서 포스트를 올렸었다.

일반적인 프로그래밍 언어에서 String은 Char들로 이뤄진 배열이다. 하지만 JS 는 배열의 작동방식이 약간 다르다. 여기서 의문점이 생겼다. JS 에서 String은 어디에 저장이 되는것일까??

 

String이 메모리에 어떻게 저장되는지 찾다가

https://blog.dashlane.com/how-is-data-stored-in-v8-js-engine-memory/

 

How is data stored in V8 JS engine memory?

Introduction After working for a few years on embedded systems and industrial PCs, focusing on low-level software development on Linux kernels, RTOS and

blog.dashlane.com

이 포스트를 보았다. 너무 길어서 원시값에 대해서만 대충 요약만 하고 넘어고자한다.

 

 

일단 V8의 메모리 공간에 대해서 조금 알고 넘어가자.

JS의 변수들은 Stack과 Heap이라는 두개의 공간에 저장된다. 대부분의 다른 언어도 마찬가지이다.

Stack

함수 실행을 위한 지역변수들이 지속적으로 할당이 일어나는 공간이다.

비교적 작은 공간을 가지고 있으며 여기 저장되는 값들은 빠르게 접근할 수 있다.

작은 사이즈인 원시값들을 저장한다. (Number, 객체에 대한 참조주소...)

Heap

스택과 마찬가지로 변수가 할당이 되는 공간이다.

스택과 비교했을때 비교적 큰 공간이 아니라 훠어어얼씬 큰 공간이다.

보통 스택에 힙 주소를 저장하여 힙에 접근하기 때문에 비교적 느리다.

위에 기술된 원시값을 제외한 비교적 용량이 큰 데이터들이 동적으로 할당된다.

 

자세한 내용은 여기서... JavaScript stack size | Better world by better software (glebbahmutov.com)

 

 

시작하기에 앞서 짚고 넘어가야 할것들.

SMI : 31비트의 부호를 가진 정수 (MAX: 0xFFFFFFFE), 숫자의 크기가 31비트를 넘어가면 공간을 2배로 늘린다.

Heap Object : Stack에서 Heap에 접근하기 위한 포인터(메모리 주소를 가리킴)를 저장하는 객체
  포인터의 크기는 OS 아키텍처의 bit수와 동일하다. ( 32bit = 4byte, 64bit = 8byte )

Object : key-value 구조, 아래는 Object의 항목들임
  Map :a pointer to the hidden class the object belongs to.
  Properties : a pointer to an object containing named properties. Properties added after initialization of the object are added to the Properties store.
  Elements : a pointer to an object containing numbered properties.
  In-Object Properties/Fast properties: pointers to named properties defined at object initialization. The number of in-objects properties depend on the object.

 

 

 

이제 JS에서 원시값이라고 하는것들을 하나씩 봅시다.

 

Integer, Float 값

변수에 1을 대입하면 SMI 값이 저장되는것과 마찬가지로 직접적으로 메모리에 저장된다.

변수에 1.2, Float 값을 할당하면 주소가 [Map] in ReadableSpace에 저장되었다 한다.

  그리고 아래 항목을 자세하게 보면 type : HEAP_NUMBER_TYPE 이라고 한다.

Map이 출력되는걸 봐서는 1을 대입했을때 stack에 저장되지만, 1.2를 대입하였을 때는 Heap에 저장된 것을 볼 수 있다.

 

String

변수에 "test"를 대입했다. 이 또한 주소가  [Map] in ReadableSpace 에 저장되었다 한다.

찾고자 했던 String이 어디에 저장되는지의 결론은 Heap 공간에 저장된다는 것이다. 작동은 안시켜 봤지만 하나의 문자만 저장한다면 아마 Stack에 저장되지 않나 싶다.

 

Boolean

undefined

null

위의 세가지 케이스도 주소가 [Map] in ReadOnlySpace에 있다고 한다. 또한, type : ODDBALL_TYPE로 모두 같은 타입을 가지고 있는걸 봐서는 코드를 실행할 때 특정 값들은 한군데 모아서 Heap에 저장하고 있는게 아닐가 싶다.

 

Symbols

새로운 심볼을 만들어 디버깅 해보면  [Symbol] in Oldspace 에 저장되었다고 한다. type : SYMBOL_TYPE, 그냥 자체적으로 저장하는가보다.

 

 

 

대충 내가 필요했던 String의 저장은 어떻게 이뤄지는지 알아봤다. 약간 복잡하다. 왜이렇게 찾기 힘들게 꽁꽁 싸매 놨는지는 모르겠지만 JS 에서 알아서 처리하기 때문에 굳이 신경쓰지 말라는것처럼 느껴진다.

무튼 중요한것은 문자열은 Heap에 담긴다는 것이다. 그렇기 때문에 성능을 최대한 개선하고자 한다면 함수 호출 시 Heap에 담기는 문자열과 같은 값들은 함수의 인자로 넘기는걸 피해보자. 프론트엔드에서는 그렇게 하기 힘들지 몰라도 백엔드에서는 충분히 가능하지 않을까??