静态方法节省内存?(非托管代码)

3
有关托管代码中静态方法的问题之后,我想知道那里的答案是否适用于像C++这样的非托管代码。
我创建了数千个实例,我的问题主要是关于静态方法。相比常规方法,这些方法是否节省内存?
谢谢,抱歉我的英语不好。
4个回答

9
所有方法都需要将它们的二进制代码存储在内存中才能运行。静态非静态方法的可执行代码(大部分)相同。
这两种类型的方法只需要存储在内存中的一个位置,因此它们不会随着类的每个实例而被复制。
现在让我们看一些代码:
class A
{
public:
   void foo();
   static void goo();
};

void A::foo()
{
004113D0  push        ebp  
004113D1  mov         ebp,esp 
004113D3  sub         esp,0CCh 
004113D9  push        ebx  
004113DA  push        esi  
004113DB  push        edi  
004113DC  push        ecx  
004113DD  lea         edi,[ebp-0CCh] 
004113E3  mov         ecx,33h 
004113E8  mov         eax,0CCCCCCCCh 
004113ED  rep stos    dword ptr es:[edi] 
004113EF  pop         ecx  
004113F0  mov         dword ptr [ebp-8],ecx 
}
004113F3  pop         edi  
004113F4  pop         esi  
004113F5  pop         ebx  
004113F6  mov         esp,ebp 
004113F8  pop         ebp  
004113F9  ret     


void A::goo()
{
00411530  push        ebp  
00411531  mov         ebp,esp 
00411533  sub         esp,0C0h 
00411539  push        ebx  
0041153A  push        esi  
0041153B  push        edi  
0041153C  lea         edi,[ebp-0C0h] 
00411542  mov         ecx,30h 
00411547  mov         eax,0CCCCCCCCh 
0041154C  rep stos    dword ptr es:[edi] 
}
0041154E  pop         edi  
0041154F  pop         esi  
00411550  pop         ebx  
00411551  mov         esp,ebp 
00411553  pop         ebp  
00411554  ret           



int main()
{
   A a;
   a.foo();
0041141E  lea         ecx,[a] 
00411421  call        foo (4111E5h) 
   a.goo();
00411426  call        A::goo (4111EAh) 
   return 0;
}

只有一些小的差异,例如将this指针推入非静态函数的堆栈中,但它们是很小的,一个不错的优化器可能会进一步减少这些差异。

关于是否使用静态函数的决定应该严格基于设计考虑,而不是内存驱动。


请问您能否解释一下您的示例中展示的内容?谢谢。 - yoni
1
@yoni 这是机器码。C++代码被编译成这个,这些是实际在你的处理器上运行的指令。 - Luchian Grigore
谢谢你的回复,但我的问题是在你的示例中,我们看到了哪些证据来支持你的说法? - yoni

4

静态方法本质上只是自由函数,因此它们的内存占用量是相同的。成员函数有一个额外的参数,所以增加的内存略大,但关注这些东西是没有意义的。

函数占用的内存量是每个类而不是每个实例。你不应该担心。


我觉得“额外参数所添加的内存”有点令人困惑。它是每次调用的成本,在调用结束时撤销,而不是像你在回答中所读到的每个函数的成本。 - Matthieu M.

2

简短回答:不行。一个方法是一个带有隐含第一个参数等于其类的函数,而静态函数则缺少这个第一个参数。实际上,情况与垃圾收集语言中的情况完全相同,因此对于其他问题的答案也完全适用。


0
静态方法和实例方法之间的区别只在于第一个参数。在C++中,所有实例方法都编译为普通函数,并替换第一个参数称为“this”,它是指向调用该方法的对象的指针。
在大多数架构上,这将是一个8字节的值,因此除非您正在进行一些非常资源严格的嵌入式系统编码,否则这并不重要。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接