静态字段和常量字段的内存消耗
本文关键字:字段 内存 常量 静态 | 更新日期: 2023-09-27 18:20:26
我有一个类,其中有一个字符串字段。这个字符串字段是常量,将来它将被移到资源文件中,但目前它将保留在我们的类中。现在的场景是,我正在制作这个类的一百多个对象。因此,我的问题是,在哪种方法中,会消耗更少的内存,为什么?
-
我应该使我的字符串变量
static
public class MyClass { public static string MyString = "My String"; }
-
我应该使我的字符串变量
const
public class MyClass { public const string MyString = "My String"; }
这是有区别的。静态变量在动态内存空间中初始化,因此会占用额外的内存空间,更不用说您需要可执行代码(额外的内存)来初始化和访问它们了。
所有常量数据都与只读存储器(ROM)中的可执行代码位于同一内存空间中,在只读存储器中,静态数据被加载到动态存储器中,您可以在动态存储器中对其进行读写。下面是以前的答案中似乎忽略的有趣部分。静态数据占用动态内存空间,但需要额外的ROM空间,在更糟糕的情况下,可能会占用两倍的内存。考虑以下内容:
class StaticData
{
static string s_static1 = "My string data";
}
class ConstData
{
const string CONST1 = "My string data";
}
类StaticData具有变量s_static1,该变量将占用单个指针的动态内存空间(通常为1个整数)。然而,它也必须初始化,因此也必须有ROM代码来初始化它。字符串数据本身通常位于ROM空间中,因为字符串数据是不可变的,并且不会占用比常量excample更多的空间。
对于ConstData类,只需要ROM存储空间,因此在大多数情况下,这是内存的最佳使用。
现在,当您考虑编译器如何使用数据时,它会变得更加有趣。除了字符串/字符数据外,常量通常在代码中的引用点直接替换。换句话说,根据使用情况,常数值直接加载到寄存器中或推送到堆栈中。在静态变量的情况下,编译器必须通过额外的代码(指针引用)从内存中读取该值,因此需要额外的ROM代码。
总之,静态代码将通过占用额外的动态内存空间和引用它所需的额外可执行代码空间来占用更多的内存。
我相信在内存方面不会有任何区别。在这两种方式中,消耗的内存是相同的。但性能上可能会有一些差异——constant
字段会更好,因为在我看来,您不希望MyString
的值被更改&常量成员是在编译时定义的,在运行时不能更改。
Constant不消耗任何内存。它将在编译时替换为已定义的值。而将成员定义为静态将根据数据类型消耗内存。
这两个选项将使用相同数量的内存。唯一的区别是,第一个允许更改MyString
的值,而第二个不允许,这可能正是您想要的。
内存方面没有区别。无论哪种方式,您都会将字符串加载到内存中一次(如果它的值还没有)。当涉及到字符串时,性能方面也不应该有太大的差异,正如KooKiz所指出的(会有值类型,但通常你不应该关心这种微优化)
如果它是一个不变的常量,则应该使它成为类外的全局。
否则,如果它必须是站点的一部分,则将其设为静态:)