Skip to content

태그: Go

GC
go
Go의 GC는 mark-sweep 방식으로 동작하며 두 가지 주요 단계로 나뉜다. 마킹: 메모리에서 살아있는 객체를 식별한다. 스윕: 죽은 객체를 해제하여 메모리를 반환한다. GC는 스윕 → 비활성 → 마킹 세 단계를 순회하며 주기적으로 진행된다. Go의 GC는 현시점의 Heap 크기와 직전 시점의 Heap 크기에 대한 증가율이 특정 정도에 다다르면 수행되는 로직으로 구현되었다. 이 때 그 정도를 정하는 변수는 GOGC라고 부른다. GOGC 값을 사용해 아래와 같이 목표 힙 메모리를 구한다. 목표 힙 메모리 = 살아있는 힙 메모리 + (살아있는 힙 메모리 + GC 루트) × GOGC / 100 예를 들어, 살아있는 힙이 8 MiB이고, GOGC가 100일 때, 목표 힙 메모리는 18 MiB이다. GO
slice
go
슬라이스는 내부적으로 사용하는 배열의 부분 영역인 세그먼트에 대한 메타 정보를 가지고 있다. 슬라이스는 크게 3개의 필드로 구성되어 있다. 내부적으로 사용하는 배열에 대한 포인터 정보 세그먼트의 길이 세그먼트의 최대 용량(Capacity) append append()가 슬라이스에 데이터를 추가할 때는 슬라이스 용량(capacity)이 아직 남아 있는 경우: 용량 내에서 슬라이스의 길이(length)를 변경하여 데이타를 추가한다. 용량(capacity)을 초과하는 경우: 현재 용량의 2배에 해당하는 새로운 Underlying array를 생성하고, 기존 배열 값들을 모두 새 배열에 복제한 후 다시 슬라이스를 할당한다. 아래 예제는 길이 0, 용량 3의 슬라이스에 1부터 15까지의 숫자를 계속 추가하면
고루틴 스케줄링
go
Go 런타임은 프로그램이 실행되는 내내 고루틴을 관리한다. Go 런타임은 모든 고루틴을 다중화된 스레드들에 할당하고 모니터링하며, 특정 고루틴이 블록되면 다른 고루틴이 실행될 수 있도록 교체하는 일을 반복한다. 이 말은 고루틴이 블록 되더라도 다중화된 스레드는 블록 되지 않는다는 것을 의미한다. CPU Core가 존재하고 있으며 OS Scheduler에 의해서 다수의 Thread가 Scheduling되어 동작하고 있는 모습을 나타내는 그림이다. Network Poller는 Network를 처리하는 별도의 독립된 Thread를 의미한다. Run Queue에는 GRQ (Global Run Queue)와 LRQ (Local Run Queue)가 2가지가 존재한다. GRQ는 의미 그대로
메모리 관리
go
Go는 힙에서 동적 할당이 필요한 메모리를 암묵적으로 할당한다. 할당이 암묵적으로 이뤄지기 때문에 코딩이 쉽지만, 메모리 할당과 해제가 명확하지 않으니 메모리 사용량이 높아질 수 있는 부분을 놓칠 가능성이 있다. Go는 참조 지향이 아닌 값 지향적 언어이다. Go 변수는 절대 객체를 참조하지 않고, 항상 객체의 전체 값을 저장한다. (포인터가 없다는 의미는 아니다.) 모든 변수 선언(함수 인자, 반환 인자, 메서드 리시버 포함)은 해당 타입 전체를 할당하거나 그 포인터만 할당한다. new(&x3C;type>)은 &x26;&x3C;type>과 동일하며, 힙 상의 포인터 박스와 별도의 메모리 블록에 타입을 할당한다. Go 할당자는 특정 스팬에 하나 혹은 여러 8KB 페이지를 포함하는 메모리