** C++의 struct에서도 동일하게 적용되는 내용이기 때문에 CS 일반 섹션에 작성했습니다.
아래 코드의 경우에는 합쳐서 16byte가 연속된 형태로 메모리에 할당된다. 허무한가?
type User struct {
Age int // 8byte
Score float64 // 8byte
}
func main() {
me := User{Age: 100, Score: 23.536}
fmt.Println(unsafe.Sizeof(me)) // 16
}
그런데 아래의 경우에도 16바이트를 출력한다. 뭐지? 이유는 "메모리 정렬" 때문이다.
아마 여러분들의 컴퓨터의 레지스터는 64비트 기반일터인데, 따라서 8의 배수를 기반으로 메모리에 할당하려고
우선 8바이트를 할당하고 4바이트를 차지하도록둡니다.
type User struct {
Age int32 // 4byte
Score float64 // 8byte
}
func main() {
me := User{Age: 100, Score: 23.536}
fmt.Println(unsafe.Sizeof(me)) // 16???
}
그림으로 설명하면 다음과 같습니다.
이러한 메모리 패딩을 최대한 비효율적으로 짜보면 아래처럼 짤 수 있겠죠
package main
import (
"fmt"
"unsafe"
)
type User struct {
A int8 // 1byte
B int64 // 8byte
C int8 // 1byte
D int64 // 8byte
}
func main() {
var user User;
fmt.Println(unsafe.Sizeof(user)) // 32
}
결론적으로는 배치를 잘못해서 14 byte가 날아가게 됩니다.
이러한 메모리 패딩을 고려하여 낭비를 줄이기 위해서는 8바이트보다 작은 필드는 크기를 고려해서 배치해야 합니다.
type User struct {
A int8 // 1byte
C int8 // 1byte
B int64 // 8byte
D int64 // 8byte
}
func main() {
var user User;
fmt.Println(unsafe.Sizeof(user)) // 24
}
이렇게 짜면 24바이트로 같은 역할을 하는 구조체를 만들수 있다는거죠! ㅎ
'💻 CS 일반 > 💻 CS 일반 (etc...)' 카테고리의 다른 글
Go로 살펴보는 오버플로, 언더플로, float간 비교 (0) | 2021.05.09 |
---|---|
Cache의 개념 (0) | 2021.01.31 |
비트 연산자와 보수에 대하여 (0) | 2020.09.29 |
기계어와 어셈블리어, IR(Intermediate representation) (0) | 2020.08.30 |
프로세스, 프로세서(CPU), Context Switching, 스레드, 멀티스레드 (0) | 2020.08.25 |