【问题标题】:If classes all contain lots of useful class variables, will it have an impact on performances?如果类都包含很多有用的类变量,会对性能产生影响吗?
【发布时间】:2012-08-08 08:36:34
【问题描述】:

每当我编写一个新类时,我都会使用大量的类变量来描述类的属性,直到当我回过头来查看我输入的代码时,我会看到 40 到 50 多个类变量,无论它们是公共的、受保护的还是私有的,它们在我定义的所有类中都被显着地使用。

尽管类变量主要由原始变量组成,如布尔值、整数、双精度值等,但我仍然有一种不安的感觉,即我的一些具有大量类变量的类可能会对性能产生影响,不管它们多么微不足道。

但是尽可能合理,如果我考虑无限的 RAM 大小和无限的 Java 类变量,Java 类可能是 RAM 中无限大的内存块,该块的第一部分包含类变量分区,并且该块的其余部分包含 Java 类中类方法的地址。有了这么多的 RAM,它的性能就很不一般了。

但上面的内容并没有让我的感受比说的更容易。如果我们考虑有限的 RAM 但无限的 Java 类变量,结果会是什么?在性能很重要的环境中真正会发生什么?

而且可能会事先提到,我不知道有很多类变量是否算作不好的 Java 实践,当所有这些变量都很重要并且所有类都已重构时。

提前致谢。

【问题讨论】:

  • 尽可能减少类变量。只是改变你的设计模式可能会有所帮助。
  • 它们是类变量还是常量(即static final)。你能不能举一个“有用的类变量”的例子,因为我觉得很难想象我们在这里谈论什么样的场景。
  • 这是数量惊人的变量。如果有的话,这应该极少是必要的。如果您发现自己更频繁地使用它,那么您的设计需要改进。

标签: java performance class variables


【解决方案1】:

性能与对象的字段数量无关。内存消耗当然可能会受到影响,但如果需要变量,您就无能为力了。 不要太担心性能。使您的代码简单、易读、可维护、经过测试。然后,如果您发现性能问题,请测量和分析以了解它们的来源,并在需要的地方进行优化。

可维护性和可读性受对象具有的字段数量的影响。 40 到 50 个字段是相当多的字段,这可能表明您的类自己做的太多,职责太多。将它们重构为许多更小的子类,并使用组合可能是一个好主意。

【讨论】:

  • +1 Maintainability and readability 几乎总是比性能更重要。事实上,我认为干净、简单、维护良好的代码即使不是最快的,通常也会表现良好。
  • 从 GC 的角度来看它是 JB。我在一个交易平台上工作,有时我们不得不将很多字段放在一个类中以减少次要 GC 所花费的时间(我们使用 CMS 收集器)。
  • 我喜欢。 +1 确保首先满足要求,然后在出现问题时担心性能。
【解决方案2】:

我希望我听起来不像是个混蛋,但在我看来,一个类中有超过 10 个属性通常是一个糟糕设计的暗示,需要说明理由。

性能方面,如果您经常需要所有这些属性,那么您将节省一些内存,因为每个对象都有一个标题。因此,您无需将所有类都放在一个类中,而是节省了一些字节。

根据您使用的垃圾收集器,分配更大的对象可能会更昂贵(CMS 垃圾收集器确实如此,但并行垃圾收集器则不然)。更多的 GC 工作 = 更少的应用运行时间。

除非您正在编写一个高流量、低延迟的应用程序,否则使用更少的类(和使用更少的内存)所带来的好处将完全被维护所需的额外工作所淹没。

【讨论】:

  • +1 我认为类设计与数据库设计没有太大区别。有时可以,甚至更喜欢让一个类有点膨胀(db 类比的第 2 和第 1 范式),特别是如果该类位于需求范围的边缘。
【解决方案3】:

在拥有一个包含大量变量的类时,我看到的最大问题是线程安全——在这种情况下,很难推断出不变量。阅读/维护这样的课程也将非常困难。

当然,如果您尽可能多地使字段不可变,那会好很多。

我尝试使用:越少越好,更容易维护。

【讨论】:

    【解决方案4】:

    我们一直被教导的一个基本原则是保持高凝聚力(一个班级专注于一项任务)和低耦合度(班级之间的相互依赖性较小,因此一个班级的变化不会影响其他班级)。

    在设计系统时,我认为应该更多地关注可维护的设计,性能会自行解决。我认为一个类可以拥有的变量数量没有固定限制,因为这将严格取决于您的要求。

    例如,如果我有一个要求,即应用程序向学生推荐一门课程,而算法需要 50 个输入(分数、爱好等),那么这些数据是在一个班级还是多个班级中可用都没有关系,作为一个整体需要将信息加载到 RAM 中以便更快地执行。

    我要再说一遍,注意你的设计,在一个类中保留不必要的变量(因为它会将非必需的信息加载到 RAM)或拆分成比需要更多的类(更多引用和因此指针)都是有害的运动)

    【讨论】:

      【解决方案5】:

      1.我总是将此作为经验法则。 一个类应该只有一个改变的理由,所以它应该只做一件事。

      2. 牢记这一点,我采用了定义此类属性所需的那些变量。

      3.我确保我的班级遵循Cohesive principle班级中的方法反映班级名称。

      4. 现在在整理完所有内容之后,如果我需要一些其他变量来计算我的课程,那么我需要使用它们,我别无选择......而且经过所有这些思考和创建类的工作几乎不会受到一些额外变量的影响。

      【讨论】:

        【解决方案6】:

        有时类变量用作静态最终常量来存储一些默认字符串,如产品名称、版本、操作系统版本等。甚至存储产品特定设置,如字体大小、类型等。这些静态变量可以保存在班级水平。

        如果您只想存储字段常量或喜欢很少更改的产品设置,您也可以使用 HashMap 代替简单的类。这可能会帮助您加快响应时间。

        【讨论】:

          【解决方案7】:

          我想提两件事: 1. 所有实例变量都存储在 RAM 的 Heap 区域中。 2.所有静态变量都存放在非Heap区(具体是方法区)。

          无论是什么类型的变量(实例或静态),最终都驻留在 RAM 中。

          现在来回答你的问题。就实例变量而言,java 的内置垃圾收集器在大多数情况下都能很好地、真正有效地工作,以保持释放内存。但是,静态变量不会被垃圾回收。

          如果您非常担心由于类中的大量变量而导致的内存问题,您可以求助于使用弱引用而不是传统的强引用。

          【讨论】:

            猜你喜欢
            • 2018-03-20
            • 2014-12-26
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2010-11-27
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多