【问题标题】:Reducing memory consumption in Java [closed]减少Java中的内存消耗[关闭]
【发布时间】:2012-09-24 04:13:52
【问题描述】:

我曾参与过一些以实现更好的性能和减少内存消耗为主要目标的项目。但是相信我,Java 中的内存消耗已经很难控制了。

这个wiki page,上面写着“Java 程序速度在某些情况下,Java 在低级和数字基准测试中与 C++ 相同。

These statistics 并没有真正显示出时间计算性能基准的主要差异。 但是,Java 中的内存使用量比 C++ 高得多,因为在 Java(32 位;在 64 位 java 中是两倍)中,每个对象有 8 字节开销,每个数组有 12 字节开销,如以上维基链接。

现在的问题是人们采取了哪些措施来最大限度地减少 Java 中的内存利用率?

请注意,我更关心内存而不是性能,因为我想不出比“编写更好的程序”和“在 JDK 中正确调整内存”更好的方法

【问题讨论】:

  • 在 java 中不能像在 c++ 中那样优化内存占用。如果内存是主要限制,那么您需要 java 有什么原因吗?
  • Java 在一个非双精度的 64 位程序中为一个对象的头部多使用了 4 个字节。 Java 通常在 64 位 JVM 中使用 32 位引用,最多 32 GB,而 C/C++ 64 位程序通常使用 64 位指针。
  • +Anshu Java哲学真的不在乎使用多少RAM,Java的重点是可扩展性,性能和标准化,如果你想要具有Java最大优势但轻量级的东西,请考虑采取看看 GOLANG,它是 Java 和 C++ 之间的中间部分
  • 如果配置正确,JVM 可以垂直扩展以优化当前负载的内存使用。选择的垃圾收集器是主要的基础砖之一,它的设置会影响整个项目。使用 G1 GC 并避免“激进堆”方法。更多细节在文章“使用正确的垃圾收集器最小化 Java 内存使用”javacodegeeks.com/2017/11/…

标签: java performance memory


【解决方案1】:

根据您的工作,您可以从不同的编程实践中受益,例如:

  • 限制在实际使用之前初始化的变量数量。
    • 只是一个通用的良好编码技巧。已初始化且暂时不需要的变量正在占用尚不需要的内存,这可能会浪费资源。
  • 在适用的情况下通过静态对象进行对象缓存。
    • 我之前曾在反射繁重的应用程序中使用它,我需要在循环中获取对象的成员列表,它可以根据可能需要的情况显着提高性能。
  • 适用的对象池
  • 如果您正在编写多线程应用程序,您可以利用线程池通过限制创建和启动新线程的工作量来提高性能。

【讨论】:

  • 对象池(以及通过扩展甚至更大程度的线程池)实际上倾向于增加内存使用,以提高性能。它的全部意义在于您持有您目前不使用的对象,假设您很快会再次需要它们。
  • 很好,绝对正确。应根据应用程序的需要谨慎使用。它可能会提高性能,但确实会增加内存使用量。它通常用于快节奏的处理应用程序,例如游戏等。线程池也是如此。
  • 其实,它并没有那么黑白分明。在创建大量对象、短暂使用它们然后丢弃它们的某些情况下,对象池可以减少内存占用。当您一直这样做时,您不仅会产生 GC 开销,而且 GC 很可能无法跟上它的步伐。因此,出于这个原因,拥有一个小的可重用对象池可能比不断创建新对象更好。
【解决方案2】:

在 java 中管理内存有两个动机。

1.避免频繁创建/删除对象。

这反过来又避免了 GC 频繁唤醒,因为这会导致一个或多个正在执行的线程挂起。

避免临时/永久内存漏洞

2。降低VM的整体内存消耗

如果您的 VM 将在具有严格内存限制的环境中运行,则需要这样做。

理想情况下,从内存的角度来看,一个编写良好的 java 程序应该尝试实现上述两个目标。 现在要实现 1,您应该执行以下操作。

  • 首选静态内存分配,即每个 VM 分配一次,而不是 动态内存分配。

  • 避免在函数中创建临时对象,这样做最多 对象可以实现一个 reset() 方法,该方法可以允许对象 重复使用

  • 了解您正在使用的 API,例如。如果你使用字符串,你会
    最终创建与修改一样多的实例。这 这同样适用于自动装箱类型。

以上几点也有助于管理或控制点2

要检查VM内存大小,您需要执行上述几点并执行以下操作

在启动 VM 时使用 Xmx 和 Xms 标志,并故意将它们的值设置为低于可能需要的值,并注意 OutOfMemoryError。

如果 OutOfMemoryError 发生,这意味着您超出了最大 VM 大小。确定原因并开始调整您的对象创建。

希望对你有帮助……

【讨论】:

    【解决方案3】:

    除了减少您创建的对象数量并尝试使您的对象短暂存在之外,您对内存无能为力。但是,Java 仍会使用它允许的所有内存以获得最佳性能。

    【讨论】:

      【解决方案4】:

      人们采取了哪些措施来最小化 Java 中的内存使用率?

      他们着眼于小型基准测试,而不是阵列大小的微观测试。

      您可以尝试比较 Java 的引用(即使在 64-JVM 上也使用 4 字节)与 C++ 共享指针(在 64 位进程上可以使用 48 字节)并得出一些不太可能的结论在实际程序中很有用。

      我更关心内存而不是性能,因为我想不出比“编写更好的程序”和“在 JDK 中正确调整内存”更好的方法

      通常您需要做的就是使用内存分析器。这将帮助您最大限度地减少 Java 中的内存消耗。

      我发现在大多数情况下,对保存每个字节的痴迷是不合时宜的。在 PC 中,一个字节的内存成本约为 5e-7 美分。或大约 2e-6 秒的时间。这些可以加起来,但如果您只节省 100 KB,则可能不值得更改任何代码来执行此操作,如果您要节省 1 GB,则可能值得花几个小时。即使您确实节省了 1 GB,内存也可以重复使用,但您的时间却不是。

      “如果内存是主要限制,那你需要java有什么理由吗?”

      我同意这一点,如果您的设备只有几 MB,即比 android 手机还小,那么 C 将是您的最佳选择。如果您的设备至少具有智能手机的容量,那么 Java 可能适合您的需求。

      【讨论】:

        猜你喜欢
        • 2013-06-13
        • 1970-01-01
        • 1970-01-01
        • 2023-03-18
        • 2015-05-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多