内存逃逸
内存逃逸: 编译器将 函数局部变量 (即应该在栈内的数据) 分配到了堆上。 为什么发生?
- 因为外部引用,编译器帮忙自动纠错。
- 闭包
- 变量大小不确定(如
slice), 编译器更倾向放在堆上 - 类型不确定 为什么要避免逃逸?
- 大量逃逸影响程序性能(堆被大幅度占用)
内存分配
一些编程语言如c,如果需要节省内存还需要自己手动管理struct中的成员变量顺序,以确保内存对齐。例如:
typedef struct {
char a; // 1 byte
uint32_t b; // 4 bytes
} Test; // 8 bytes
typedef struct {
uint32_t b; // 4 bytes
char a; // 1 byte
} Test2; // 8 bytes在这里,由于char只占1个字节,而uint32_t占4个byte,为了内存对齐,编译器会在char后面填充3个byte,使得Test的大小为8个byte。
如果我们将uint32_t放在前面(即是Test2),那么Test2的大小就只有5个byte了。当然,实际上最后Test2的大小为8个byte,因为struct的内存大小必须是其最大成员大小的整数倍。也就是说在这里要4的倍数,那么可能就要迷惑了,那讲这个干嘛?
其实是因为如果你想我一样是个想到哪里写到哪里的人,那么最后可能会变成这样:
typedef struct {
char a; // 1 byte
uint32_t b; // 4 bytes
char c; // 1 byte
uint32_t d; // 4 bytes
} Test; // 16 bytes
typedef struct {
uint32_t b; // 4 bytes
uint32_t d; // 4 bytes
char a; // 1 byte
char c; // 1 byte
} Test2; // 12 bytes或者可能再多一点点
typedef struct {
char a; // 1 byte
double b; // 8 bytes
char c; // 1 byte
uint32_t d; // 4 bytes
} Test; // 24 bytes
typedef struct {
double b; // 8 bytes
uint32_t d; // 4 bytes
char a; // 1 byte
char c; // 1 byte
} Test2; // 16 bytes