打印
[技术文档]

为什么你写的代码占用内存这么大?

[复制链接]
13737|50
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
jcky001|  楼主 | 2022-12-8 14:37 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
你做的模块,测试反馈说,进去就卡顿,按钮点击半天才反应。


这是为什么呢?

要想知道这个问题的答案,首先需要搞懂怎样估算对象和结构体的大小。
一、如何估算结构体的大小
结构是值类型,它的结构体的实例是存放在栈中或者堆中。
结构体在内存中所占的大小,就是其字段所占的大小,但是,它的大小并不是所有字段大小相加,而是存在一个对齐的规则,在默认的对齐规则中,基本类型字段是按照自身大小对齐的,如byte是按1字节对齐。




struct A  {    byte a1;  }

如上面这个结构体的大小就是1字节,如果是下面这个:



struct A{  byte a1;  int a2;}

这个结构体所占内存大小是8字节,因为int是4字节对齐的,所以只能从第四个字节开始。

如果再添加一个字段:



struct A{byte a1;int a2;byte a3;}

这个结构体大小是12,由于struct本身也要是对齐的,所以它的对齐规则是按照其中元素最大的对齐规则决定的。也就是说上面这个结构体要按照4字节对齐,不足4字节要补齐,所以是12个字节大小

如果想要优化它的大小,可以调整顺序如下:



struct A{  byte a1;  byte a3;  int a2;}

这个时候这个结构体所占的大小就是8字节了。
二、如何估算类的大小
类是引用类型,它的对象实例存放在堆中,对象实例一定是会占用堆内存的,而在栈中,保存的是实例的引用。对象在堆中分成3个区域,vtable、monitor和字段。
其中vtable是类的共有数据,包含静态变量和方法表,这个应该就是类本身所占用的大小和具体的对象无关。monitor是线程同步用的,这2个指针分别占用一个inptr.Size大小,字段是从第9个字节或17个字节开始的,字段的对齐规则和结构体的对齐规则相同,区别是Mono中对象的实例会把引用类型的引用放在最前面。一个对象实例的大小就是 inptr.Size *2+字段的大小。
通过调整字段的顺序,也可以优化对象的大小。
还可以通过StructLayoutAttribute自定义类和结构体的对齐方式。




[StructLayout(LayoutKind, Sequential, Pack = 1)]public struct A {  byte a1;  int a2;  byte a3; }

上面这个结构体强制按照1字节对齐,所以他的大小是6字节,但这样做可能会降低性能。
所以具体情况还是要具体分析,懂得了如何估算结构体和类的大小,就更容易知道该如何使用它们了。
我们的目标就是让测试下岗,因为没有BUG他就没工作了


使用特权

评论回复

相关帖子

沙发
weifeng90| | 2022-12-8 17:23 | 只看该作者
要编写精简高效的代码是个大调站

使用特权

评论回复
板凳
liu96jp| | 2023-3-8 13:13 | 只看该作者
代码写的大是因为定义的全局变量比较多

使用特权

评论回复
地板
t1ngus4| | 2023-3-8 14:23 | 只看该作者
一般得看你程序习惯的,要是全局变量多也会导致代码内存占用的大

使用特权

评论回复
5
q1ngt12| | 2023-3-8 15:30 | 只看该作者
可以习惯性的使用结构体,这样会好很多

使用特权

评论回复
6
suw12q| | 2023-3-8 16:34 | 只看该作者
其实都是这样,有很多时候会定义一个buf,这个buf如果是全局变量,那占得空间可太大了

使用特权

评论回复
7
lamanius| | 2023-3-8 17:45 | 只看该作者
楼主讲的通透,其实就是善用结构体和联合体

使用特权

评论回复
8
l1uyn9b| | 2023-3-8 20:32 | 只看该作者
我一般程序都是这样,能用局部变量就不用全局变量,能用结构体就用结构体

使用特权

评论回复
9
p0gon9y| | 2023-3-9 07:02 | 只看该作者
编程的好习惯就是要这么养成的,不能因为现在的MCU资源很多,就随意浪费,哈哈

使用特权

评论回复
10
ex7s4| | 2023-3-9 08:16 | 只看该作者
还就就是建议全局变量少用,也会减少很多的空间的

使用特权

评论回复
11
g0d5xs| | 2023-3-9 10:09 | 只看该作者
讲的不错,属实是结构体是个降低存储占用的好方法,而且还可以方便修改

使用特权

评论回复
12
zhizia4f| | 2023-3-9 13:22 | 只看该作者
有很多工程师喜欢用结构体就是因为这个内存占用问题

使用特权

评论回复
13
claretttt| | 2023-6-10 16:05 | 只看该作者
如果代码的逻辑非常复杂,包含了大量的条件语句、循环语句和函数调用等,那么生成的机器码就会非常庞大,从而导致代码占用内存过大。

使用特权

评论回复
14
sdCAD| | 2023-6-10 16:10 | 只看该作者
使用过多的库函数也会占用较多的内存空间。

使用特权

评论回复
15
maqianqu| | 2023-6-10 16:15 | 只看该作者
如果采用了低效的算法或者没有进行优化,就容易导致代码占用内存过大。

使用特权

评论回复
16
bestwell| | 2023-6-10 16:28 | 只看该作者
如果定义了过多的全局变量或者静态变量,就会占用大量的内存空间

使用特权

评论回复
17
earlmax| | 2023-6-10 16:42 | 只看该作者
如果编译选项未设置正确,编译器可能会生成一些冗余的代码,从而增加程序的大小。

使用特权

评论回复
18
eefas| | 2023-6-10 16:51 | 只看该作者
在需要的情况下启用硬件加速功能、DMA传输模式等,以最大限度地减小代码空间的占用。

使用特权

评论回复
19
burgessmaggie| | 2023-6-10 16:58 | 只看该作者
优化算法和实现方式,避免使用过于复杂或低效的算法。

使用特权

评论回复
20
sheflynn| | 2023-6-10 17:04 | 只看该作者
可以考虑将一些重复代码提取出来,避免过多的宏定义。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1526

主题

4638

帖子

6

粉丝