当前位置:首页 > 内存 > 正文

golang内存管理

  • 内存
  • 2024-06-10 07:27:11
  • 6860

一、Go语言中恰到好处的内存对齐

在开始之前,我希望你能计算一下part1占用的总大小。

输出结果:

经计算,Part1结构体占用内存大小为1+4+1+8+1=15字节。我想有些朋友是这么算的,似乎并没有什么问题。

实际情况是怎样的呢?我们看一下实际调用如下:

输出结果:

最终输出占用32字节。这与之前预想的结果完全不同。这充分证明了之前的计算方法是错误的。为什么?

这里需要提到“内存对齐”的概念,以便我们能够以正确的姿势进行计算。接下来详细说一下它是什么。

有的朋友认为读取内存只是字节数组的简单排列。

上图展示了一个陷阱和胡萝卜读取记忆的方法。然而CPU实际上并不是逐字节读写内存的。相反,CPU一次读取内存一个块,块大小可以是2、4、6、8、16字节等。我们将块大小称为内存访问的粒度。如下所示:

示例假设访问粒度为4。CPU以每4字节的访问粒度读写内存。这才是正确的态度。

另外,作为一名工程师,这个知识点你是有必要学习的:)

上图中,假设阅读开始来自索引1。将会出现崩溃问题。因为它的内存访问边界没有对齐。所以CPU会做额外的处理工作。如下:

从上面的过程可以得出,不做“内存对齐”有点“繁琐”。由于这样增加了很多耗时的动作

假设完成了内存对齐,从index0读取了4个字节,那么只需要读取一次,不需要额外的操作。这显然更加高效,是一种以空间换时间的标准方式

不同平台上的编译器都有自己默认的“对齐系数”,可以通过#pragmapack(n)预编译命令进行更改。n指“对准系数”。一般来说,我们常用的平台的系数如下:

另外,需要注意的是,不同的硬件平台所占用的尺寸和方向值可能会有所不同。因此,本文中的数值并不明确。调试时需要考虑机器的实际情况。

输出结果:

在Go中,可以不安全地调用.Alignof返回对应类型的对齐情况。通过观察输出结果可以看到,基本都是2^n,最大不会超过8。这是因为我的笔记本电脑编译器(64位)的默认对齐因子是8,所以最大值不会超过这个数字。

上一节提到了结构体中的成员变量必须是面向字节的。因此,当然,作为最终结果的结构也必须是面向字节的。

接下来,我们分析“它”经历了什么,影响了“预期”的结果

在每个之后member变量是对齐的。根据规则2,整个结构体本身也一定是面向字节的,因为可以发现它可能不是2^n,也不是偶数倍。显然不符合对齐规则

根据规则2,可以得出对齐值为8。偏移量现在为25,它不是8的倍数。所以偏移量为32。对齐结构体

Part1内存布局:axxx|bbbb|cxxx|xxxx|dddd|dddd|exxx|xxxx

通过本节的分析我们可以看到前面的“为什么”是“计算”错了吗?

这是因为实际的内存管理并不是基于“一根胡萝卜一个坑”的想法。但一点一点地。这篇读写文章是通过用空间换取时间(效率)的思想来完成的。另外,还需要考虑到不同平台的内存运行情况。

在上一节中可以看出,结构体的内存根据成员变量的类型而变化,对齐和其他操作。那么如果我们假设场序不同的话,会不会有什么变化呢?让我们一起尝试一下:-)

输出结果:

根据结果,我们会惊讶地发现,即使是成员变量字段顺序的“简单”更改也会改变Body结构占用尺寸

接下来我们一起来分析part2,看看它的内部和之前有什么不同导致了这样的结果?

符合规则2,无需额外对齐

Part2内存布局:ecax|bbbb|dddd|dddd

通过比较part1和part的内存布局2:你会发现两者有很大的区别。如下:

仔细一看,Part1中有很多padding。显然它占用了大量空间。内饰是什么样子的?

通过本文的介绍,我们可以看到,不同类型需要字节对齐来保证内存访问边界

就不难理解为什么结构体要调整字段顺序了成员变量的数量可以减少结构的大小,因为它巧妙地减少了填充的存在。让它们更加“紧凑”。这对于加深对Go内存布局的印象以及优化大对象非常有帮助


二、golang和java处理tcp效率提问者想问“golang和java在TCP处理效率上有什么区别?”golang和java在TCP处理效率上的差异包括内存管理、并发处理能力、代码可读性和简单性。:
1。内存管理:与Java相比,Golang使用的内存更少,并且避免了Java堆中的垃圾回收问题。当处理大量TCP连接时,这些好处变得更加明显。
2。并发处理能力:Golang以其对并发的原生支持而闻名。如果需要同时处理多个TCP连接,Golang具有性能优势。
3。代码可读性和简单性:Java通常需要更多的代码和面向对象的设计,以使其更易于维护和扩展。Golang的语法更加简洁,使得在编写简单的TCP应用程序时更加有效。
三、嵌入式golang占用内存高内置golang内存使用率高可能是由于缓存造成的。
清除日志后,我惊讶地发现内存突然下降到了20M。
嵌入式系统由硬件和软件组成。这是一个可以独立工作的设备。其软件的内容仅包括软件的执行环境及其操作系统。硬件包括信号处理器、存储器、通信模块等。与传统的计算机数据处理系统相比,嵌入式系统有很大不同。由于不存在合适的大容量存储介质,它们无法实现大容量存储功能。使用的存储介质大部分是E-PROM、EEPROM等。软件部分使用。API编程接口作为开发平台的核心。嵌入式系统的底层是中央处理单元,包括运算单元和控制器模块。在CPU的基础上,进一步配备了内存模块、电源模块、复位模块等,形成了通常所说的最小化。系统。随着技术的进步,集成电路制造商通常将许多外围器件集成到一块集成电路中,使其使用起来更加方便。这种芯片通常称为微控制器。在微控制器的基础上,进一步扩展功率测量和检测模块、执行模块和支撑软件,形成一个具有特定功能的完整单元,称为嵌入式系统或嵌入式应用。