golang 内存对齐和填充规则

内存对齐和填充规则

  1. 对齐要求:每个数据类型的起始地址必须是其大小的倍数。

    • int8(1字节):不需要对齐。
    • int16(2字节):起始地址必须是2的倍数。
    • int32(4字节):起始地址必须是4的倍数。
    • int64(8字节):起始地址必须是8的倍数。
  2. 填充规则:如果当前偏移量不是下一个成员变量对齐要求的倍数,则编译器会在前一个成员后插入“填充字节”,以使下一个成员的起始地址满足对齐要求。

  3. 结构体总大小:结构体的总大小必须是其最大成员对齐大小的倍数,必要时会在结构体末尾添加额外的填充字节。

示例解析

示例 1:未优化的结构体
type Unoptimized struct {a int8   // 1 byteb int32  // 4 bytes, 需要4字节对齐c int16  // 2 bytes, 需要2字节对齐
}
  • a 占用 1 字节,起始地址为 0。
  • b 需要 4 字节对齐,但 a 只占用了 1 字节,因此在 a 后面需要填充 3 字节,使得 b 的起始地址为 4。
  • c 需要 2 字节对齐,b 占用 4 字节,所以 c 的起始地址为 8,不需要额外填充。
  • 结构体总大小为 10 字节(1 + 3 + 4 + 2),但为了使结构体大小为 4 字节对齐(最大成员 b 是 4 字节对齐),需要在末尾再填充 2 字节。

最终结构体大小为 12 字节。

示例 2:优化后的结构体
type Optimized struct {b int32  // 4 bytes, 需要4字节对齐c int16  // 2 bytes, 需要2字节对齐a int8   // 1 byte, 不需要对齐
}
  • b 占用 4 字节,起始地址为 0,符合 4 字节对齐。
  • c 需要 2 字节对齐,b 占用 4 字节,所以 c 的起始地址为 4,不需要额外填充。
  • a 占用 1 字节,c 占用 2 字节,所以 a 的起始地址为 6,不需要额外填充。
  • 结构体总大小为 7 字节(4 + 2 + 1),但为了使结构体大小为 4 字节对齐(最大成员 b 是 4 字节对齐),需要在末尾再填充 1 字节。

最终结构体大小为 8 字节。

图解填充规则

假设我们有一个结构体:

type Example struct {a int8   // 1 byteb int16  // 2 bytesc int32  // 4 bytes
}

我们可以用图来表示内存布局:

Offset: 0  1  2  3  4  5  6  7  8  9 10 11+--+--+--+--+--+--+--+--+--+--+--+--+| a| P| P| P| b| b| P| P| c| c| c| c|+--+--+--+--+--+--+--+--+--+--+--+--+
  • a 占用 1 字节,后面填充 3 字节(P 表示填充字节)。
  • b 占用 2 字节,后面填充 2 字节。
  • c 占用 4 字节。

调整顺序后:

type Example struct {c int32  // 4 bytesb int16  // 2 bytesa int8   // 1 byte
}

内存布局变为:

Offset: 0  1  2  3  4  5  6  7+--+--+--+--+--+--+--+--+| c| c| c| c| b| b| a| P|+--+--+--+--+--+--+--+--+
  • c 占用 4 字节。
  • b 占用 2 字节。
  • a 占用 1 字节,后面填充 1 字节。

最终结构体大小为 8 字节,比原来的 12 字节更紧凑。

总结

通过将占用较大内存空间的成员放在前面,可以减少编译器为了对齐而插入的填充字节数量,从而使结构体更加紧凑,节省内存。你可以使用 unsafe.Sizeof()unsafe.Alignof() 来验证这些结构体的实际大小和对齐方式。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/27556.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java 入门 (超级详细)

一、什么是Java Java是一种高级编程语言,由Sun Microsystems公司于1995年推出。Java具有跨平台性、面向对象、健壮性、安全性、可移植性等特点,被广泛应用于企业级应用开发、移动应用开发、大数据处理、云计算等领域。Java程序可以在不同的操作系统上运…

02_NLP文本预处理之文本张量表示法

文本张量表示法 概念 将文本使用张量进行表示,一般将词汇表示为向量,称为词向量,再由各个词向量按顺序组成矩阵形成文本表示 例如: ["人生", "该", "如何", "起头"]># 每个词对应矩阵中的一个向量 [[1.32, 4,32, 0,32, 5.2],[3…

【实战 ES】实战 Elasticsearch:快速上手与深度实践-1.4.2内存与磁盘配置陷阱

👉 点击关注不迷路 👉 点击关注不迷路 👉 点击关注不迷路 文章大纲 Elasticsearch内存与磁盘配置深度避坑指南1. 内存管理核心原理1.1 内存分配矩阵1.2 内存压力预警线 2. 堆内存配置陷阱解析2.1 错误配置案例2.2 正确配置公式2.3 堆内存与分…

每日一题-奶酪题(蓝桥杯)【模拟】

题目要求 题目思路 假设有一个立方体奶酪,N2 1✖1✖N的奶酪块有3种(x方向,y方向,z方向) 如果x方向上想放 1✖1✖N的奶酪块,需要x方向上的有连续n个奶酪块被切走。同理,y方向和z方向也一样 …

git详细使用教程

文章目录 一、 git介绍与安装1、git介绍2、git的安装3、git使用前的说明 二、git的基础使用1、走进git之前2、git基础使用1、git init 项目初始化(init)成仓库(repository)2、git add 管理文件3、git commit 把文件提交到仓库&…

iOS接入Flutter项目

首先要把iOS项目和flutter项目统一目录下,而且需要注意的是flutter是module。 第一步:Flutter相关内容的创建 module创建命令: flutter create --templatemodule my_flutter,之后再执行 flutter pub get flutter build ios …

SEKI —— 基于大型语言模型的自进化与知识启发式神经架构搜索

01、项目概述 我们引入了一种基于新型大型语言模型( LLM )的神经架构搜索( NAS )方法,名为 SEKI 。SEKI 受到现代 LLM 中思维链( CoT )范式的启发,分为两个关键阶段运行&#xff1a…

【现代深度学习技术】卷积神经网络03:填充和步幅

【作者主页】Francek Chen 【专栏介绍】 ⌈ ⌈ ⌈PyTorch深度学习 ⌋ ⌋ ⌋ 深度学习 (DL, Deep Learning) 特指基于深层神经网络模型和方法的机器学习。它是在统计机器学习、人工神经网络等算法模型基础上,结合当代大数据和大算力的发展而发展出来的。深度学习最重…

探秘基带算法:从原理到5G时代的通信变革【一】引言

文章目录 一、引言1.1 研究背景与意义1.2 研究目的与方法1.3 研究内容与创新点 本博客为系列博客,主要讲解各基带算法的原理与应用,包括:viterbi解码、Turbo编解码、Polar编解码、CORDIC算法、CRC校验、FFT/DFT、QAMtiaozhi/解调、QPSK调制/解…

Free Auto Clicker - 在任意位置自动重复鼠标点击

“想让鼠标自己动起来,解放双手去做更有趣的事?”Free Auto Clicker 就像你的数字小助手,能在任意位置自动重复点击鼠标。从玩游戏到刷网页,这款免费工具让你告别枯燥的重复操作,效率瞬间起飞! 你有没有想…

【SQL】MySQL中的字符串处理函数:concat 函数拼接字符串,COALESCE函数处理NULL字符串

MySQL中的字符串处理函数:concat 函数 一、concat ()函数 1.1、基本语法1.2、示例1.3、特殊用途 二、COALESCE()函数 2.1、基本语法2.2、示例2.3、用途 三、进阶练习 3.1 条件和 SQL 语句3.2、解释 一、concat &…

蓝桥杯web第三天

展开扇子题目, #box:hover #item1 { transform:rotate(-60deg); } 当悬浮在父盒子,子元素旋转 webkit display: -webkit-box:将元素设置为弹性伸缩盒子模型。-webkit-box-orient: vertical:设置伸缩盒子的子元素排列方…

VSCode知名主题带毒 安装量900万次

目前微软已经从 Visual Studio Marketplace 中删除非常流行的主题扩展 Material Theme Free 和 Material Theme Icons,微软称这些主题扩展包含恶意代码。 统计显示这些扩展程序的安装总次数近 900 万次,在微软实施删除后现在已安装这些扩展的开发者也会…

离散傅里叶变换(Discrete Fourier Transform, DFT)及其在图像处理中的应用

离散傅里叶变换(DFT)及其在图像处理中的应用 什么是离散傅里叶变换? 离散傅里叶变换(Discrete Fourier Transform, DFT)是一种强大的数学工具,用于将离散信号从时域(或空间域)转换…

金融支付行业技术侧重点

1. 合规问题 第三方支付系统的平稳运营,严格遵循《非银行支付机构监督管理条例》的各项条款是基础与前提,其中第十八条的规定堪称重中之重,是支付机构必须牢牢把握的关键准则。 第十八条明确指出,非银行支付机构需构建起必要且独…

JavaWeb-jdk17安装

下载jdk17 地址:https://www.oracle.com/java/technologies/downloads/#jdk17-windows 安装jdk 配置环境变量 右键点击我的电脑>属性>高级系统设置>环境变量 在系统变量Path变量中添加 测试 java -version javac -version

java后端开发day24--阶段项目(一)

(以下内容全部来自上述课程) GUI:Graphical User Interface 图形用户接口,采取图形化的方式显示操作界面 分为两套体系:AWT包(有兼容问题)和Swing包(常用) 拼图小游戏…

[Web 安全] PHP 反序列化漏洞 —— PHP 魔术方法

关注这个专栏的其他相关笔记:[Web 安全] 反序列化漏洞 - 学习笔记-CSDN博客 PHP 魔术方法 - 简介 - PHP 魔术方法 - 简单教程,简单编程PHP 中,以两个下划线 ( __ ) 开头方法称之为 「 魔术方法 」 这些 「 魔术方法 」 在 [PHP](/l/yufei/php…

【音视频】音频基础

一、音频基础 1.1 声音的物理性质 ——振动 声音是一种由物体振动引发的物理现象,如小提琴的弦声等。物体的振动使其四周空气的压强产生变化,这种忽强忽弱变化以波的形式向四周传播,当被人耳所接收时,我们就听见了声音。 1.2 声…

Hive-04之存储格式、SerDe、企业级调优

一、主题 hive表的数据压缩和文件存储格式hive的自定义UDF函数hive的JDBC代码操作hive的SerDe介绍和使用hive的优化 二、要点 1. hive表的文件存储格式 Hive支持的存储数的格式主要有:TEXTFILE(行式存储) 、SEQUENCEFILE(行式存储)、ORC&…