【问题标题】:Do static members help memory efficiency?静态成员有助于提高内存效率吗?
【发布时间】:2010-12-02 13:40:16
【问题描述】:

如果我有一个类,我希望在内存敏感的应用程序中的数千个实例中使用它,如果我将静态功能分解为静态成员是否有帮助?

我想静态方法和变量每个类存储一次,而对于非静态成员,必须为每个实例存储一些东西。

有了成员变量,看起来还是挺清楚的,但是方法存储了什么样的数据呢?

我正在使用 Java,但我想一些通用规则也适用于其他托管环境(例如 .NET)。

【问题讨论】:

    标签: java memory-management


    【解决方案1】:

    静态方法和非静态(实例)方法在幕后的唯一区别是额外的隐藏参数(this)被传递给实例方法,并且可以使用间接调度调用实例方法(如果虚拟的)。没有占用额外的代码空间。

    编辑:


    我的回答集中在方法上,但仔细阅读后,我发现问题更多的是关于静态数据。是的,静态数据在某种意义上会节省内存,因为它只有一个副本。当然,数据是否应该是静态的更多的是数据的含义或用途的函数,而不是内存节省。

    如果您需要拥有大量对象并想节省内存,您可能还需要调查使用'Flyweight' pattern 是否适用。

    【讨论】:

    • 不,但是每次你创建一个对象的实例时,它都会分配到内存中,对于静态对象,这永远不会发生,因为你只有一个对象。
    • 完全没问题,专注于方法。我想我的静态数据很直接,而且,正如你所说,无论如何,意义在那里更重要。
    • 没有所谓的“静态对象”
    • 嘿,没错,不过我通常不太喜欢在意确切的术语,只要人们能理解我:) 如果他们不理解,那就打我一巴掌
    • 是的,使用静态方法可以节省内存,因为如果在整个应用程序中多次访问某个方法,则无需每次都创建实例来调用该方法。只需将该方法设为静态,我们就可以节省大量内存。
    【解决方案2】:

    不应以效率为由做出决定,而应以正确性为基础。

    如果您的变量代表每个实例的不同值,则它应该是一个实例变量。

    如果您的变量是与类型关联的公共值而不是类型的单个实例,则它应该是静态变量。

    但是,您是对的 - 如果您有一个静态变量,那么您不会为每个实例“付费”。这只是增加了一个额外的理由,使变量在它们不代表对象状态的一部分时变为静态。

    当您在问题中提到方法时,您是在谈论局部变量吗?您将为每个方法调用(包括递归调用)获得一组新的局部变量。但是,这不会创建一组新的静态或实例变量。

    【讨论】:

    • 老实说,我什至没有考虑过局部变量。我主要想知道哪些数据与声明的方法相关联,以及静态与非静态之间有何不同。
    • 我一直希望正确性通过智能 JVM、操作系统和硬件开发人员的方式给我带来效率。 ;-)
    【解决方案3】:

    如果您将成员变量设为静态,则可以为每个实例节省内存(假设有多个实例),但真正的收获是您不必努力使所有这些非静态成员与每个成员保持一致其他,并且您不需要当前实例即可访问静态成员。

    如果您将方法设为静态,则每次嵌套调用都会在堆栈上保存几个字节(没有隐含的 'this' 参数),但这仅在您执行 very 繁重时才有意义递归。当然,如果函数需要知道您正在处理哪个实例,则无论如何您都需要一个显式参数来替换隐含的 'this',因此您一无所获。

    拥有静态方法或非静态方法没有每个实例的成本。费用发生在通话中。

    使用静态方法的真正原因是因为没有实例——至少在您调用该方法时是这样。例如,您可以使用静态方法来创建和初始化实例(“工厂”设计模式之一),或引用单例实例。

    【讨论】:

      【解决方案4】:

      简单的答案是肯定的。每次没有实例时创建一个实例就等于重新创建整个对象,静态方法和变量通常会消耗更少的内存,具体取决于它们的使用方式。当然,如果您只需要在整个程序中创建一个实例,那也没有什么区别。请记住,您始终可以将实例作为引用传递,而您不能拥有静态对象并且需要重用它们。

      【讨论】:

      • 乍一看,至少在被调用之前,静态(或非静态)方法消耗的唯一内存是其实现代码。拥有一个从未使用过的隐式“this”参数应该没有什么区别——决定方法代码大小的是方法的复杂性,而不是它是否被声明为静态。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-22
      • 2023-03-21
      • 1970-01-01
      • 2015-01-20
      • 2011-12-01
      • 1970-01-01
      相关资源
      最近更新 更多