javascript_Actually_work

자바스크립트의 기본적으로는 단일스레드로 컴파일이 필요없는 동적 언어이다.

목적: 클라이언트단 (브라우저)에서 자바스크립트가 어떻게 동작되어 지는지 패킷이 넘어오고 실행되는 부분의 이해를 하기위해 스터디

동적 언어 vs 정적 언어

두가지 언어는 대표적으로 동적(파이썬, 자바스크립트) 정적(자바, c++, 스칼라)등이 있다. 동적 언어의 경우는 자료형이 프로그램이 실행 되는 시점에서 정해지게 된다. 런타임 언어라고도 하며 인터프리터 언어라고 할수 있다. 초기에 배우기 쉽고 구동되는 과정에서 바로바로 코딩을 수정해서 적용해 볼수 있으며 개발 속도가 빨라 질수 있다. 하지만 너무 많은 변수가 있어 사용함에 있어서 신중하고 체계적인 방법이 필요하다.

정적언어는 그와 반대로 컴파일전에 자료형을 정해주는 언어로 잘못된 선언이 되어있을 경우 컴파일시 오류가 되어 실행 자체가 되지 않는다. 에러를 검출 하기 좋고 안정적이라고 할 수 있다. 또한 메모리 누수 등 부자적인 문제도 쉽게 잡아 낼수 있다. 하지만 초반에 설정하는 것등과 인터프리터 언어에 비해 실행 속도는 빠르지만 개발속도가 빠르다고는 할수 없고 런닝커브가 살짝 있을 수 있다.

V8엔진

구글에서 개발한 자바스크립트 엔진이다. 실행 환경은 구글 크롬, Nodejs등이 있다. 모질라 진형에서 만든 Rhino가 있지만 아직까지는 가장 인기 있는 엔진은 V8 엔진이다.

이전 스파이더몽키엔진에 비해 인터프리터대신 머신코드를 사용하여 바이트코드와 같은 중간 코드를 생산 하지 않는다. 이로 하여 실행 속도를 높였다.

v8엔진은 이 과정에서 몇개의 스레드를 이용한다. 메인 스레드는 코드를 컴파일 하고 실행하며 최적화를 위한 스레드가 존재하고 프로파일러 스레드는 런타임에 현재 상태를 보고하여 최적화를 돕는다. 가비지 컬렉터를 위한 스레드가 있다.

엔진의 구성요소는 메로리 힙, 호출 스택으로 나눌수 있다.

V8엔진의 최적화 방법 1. 인라이닝

인라이닝이란 호출 지점(함수가 호출된 곳의 코드 위치)을 호출된 함수의 내용으로 바꾸는 과정. (코드의 양은 길어지지만 추적 과정이 생략) 이러한 단순한 과정으로 이후의 최적화가 더욱 큰 의미를 가지게 됨.

V8엔진의 최적화 방법 2. 히든 클래스

자바스크립트는 프로토타입 기반 언어라 클래스의 계념이 없어 객체는 복제하는 과정에서 생성된다. 그래서 쉽게 객체의 속성을 교체하는것이 가능하다. 이건 편한기능이긴 하나 안좋은 결과를 가져오기도한다... 한편 자바스크립트의 인터프리터는 딕서너리형태로 속성값의 위치를 메모리에 저장한다. 자바의 경우 컴파일전에 미리 정의된 객체 안에 저장하기 때문에 효율적으로 값을 호출 할수 있지만 자바스크립트는 메모리 상에서 위치를 찾아내는 것이기 때문에 효율적이지 못하다. 히든 클래스는 이런점을 개선하려고 고정 객체 레이아웃을 사용한다. 객체가 생성되면 히든 클래스를 메로리상의 위치에 대한 설명을 달아서 생성한다.

V8엔진의 최적화 방법 3. 인라인 캐싱

최근 메소드 호출에 파라메터로 전달된 객체 타입의 캐시를 유지하고 이 정보를 이용해 앞으로 파라메터로 넘어올 객체의 타입에 대한 가정을 한다. 만약 V8이 메소드에 전달될 객체 타입에 대한 가정을 잘(?)할 수 있으면 객체의 속성에 접근할 방법을 알아내는 과정을 수행하지 않아도 되며 그 대신 객체의 히든 클래스에 대해 이전에 찾아서 저장했던 정보를 사용한다.

특정 객체에 메소드가 호출될 때마다 V8엔진은 특정 속성에 접근하기 위한 오프셋을 계산하기 위해 해당 객체의 히든클래스를 뒤져봐야 한다. 동일한 히든 클래스의 동일한 메소드에 대해 두 번의 성공적인 호출을 마치고나면 V8은 히든클래스를 찾는 것을 생략하고 단순하게 스스로 해당 객체 포인터에 속성 오프셋을 더해 놓는다. 동일한 모든 호출에 대해서는 오프셋을 이용해 직접 메모리 주소로 간다.