【问题标题】:How to (not) deal with high memory uses?如何(不)处理高内存使用?
【发布时间】:2015-11-29 19:36:21
【问题描述】:

我是分析 Java 应用程序的新手,当我看到我的小应用程序可能占用 800MB 内存是整个操作系统的两倍并且经过一些用户交互后大约 450MB 时,我不确定。

所以我写了一些关于内存分配和 gc 工作原理的文章,似乎 JVM 尽了最大的努力,而且大多数情况下,你的应用程序不需要那么多内存来运行。

所以我测试了我可以在不使应用程序崩溃的情况下限制堆的多少,并在 -Xmx32MB 处停止测试。

令我惊讶的是,除了应用程序使用的内存减少了近 30 倍这一事实之外,没有明显的性能损失。

所以现在我想知道...

(1) ... 如果有任何限制堆的缺点?

(2) ... 如果限制堆是常见的,还是建议让 JVW 决定它需要和想要使用多少内存?

(3) ... 找出应用程序需要运行的最小内存大小的最佳方法是什么? (我只是感兴趣)

(4) ... 在限制堆时我是否会遇到性能损失?

提前谢谢你!

【问题讨论】:

    标签: java performance profiling heap-memory


    【解决方案1】:

    您使用 new 的次数可能比您真正需要的要多得多。

    如果是这样,也是在影响你的表现,因为new不便宜,就算你不算gc

    有一种快速查找的方法。 取几个样本,如this post。 如果您发现其中有两个以上在做new,那就是您的问题。

    人们经常做的是将new 放在一个循环中,而他们也可以把它放在外面。

    一个相关的问题是他们可能会做很多string + string + string,这会在下面做很多new-ing,而他们也可以使用字符串生成器。

    【讨论】:

    • 我知道new 很昂贵,我避免在循环中使用它。但是我从来没有对字符串生成器给予太多关注,并且会读到它。谢谢。
    • 我很惊讶!我在我的应用程序中实现了字符串生成器,现在char[] 实例几乎翻了一番,但应用程序需要的内存比以前少了 10 倍。谢谢!
    • @parboiledRice:是的 :) 这就像一张信用卡。字符串之间的那个小“+”让您很容易花费超出您的承受能力。
    【解决方案2】:

    对 1 和 4 的回答非常简短:是的。对 2 的非常简短的回答:否。

    您的垃圾收集器将不得不做更多不利于性能的工作。第三个问题很有趣。 你是在嵌入式或有限的东西中运行吗?它是一个巨大的多线程应用程序吗?您的应用程序是否需要超过可用 RAM? 如果您对这些问题中的任何一个回答“是”,则运行分析器,而不是使用不同的内存分配,尝试查看您的代码在哪里占用了您的内存?您是否使用了可以使用本机数据类型(例如 byte[])的精美对象(例如 List)?

    【讨论】:

    • 这些问题是在分析我的应用程序后才想到的,因为在我看来它使用了很多内存并且我不知道 JVM 是如何分配内存的。出现高内存使用是因为我的应用程序必须比较大量字符串并生成 ~60000 char[]。我使用LinkedLists 并用ArrayLists 替换它,因为没有删除、添加或搜索,而且它们似乎需要更少的内存。但目前没有必要。我只是感兴趣。
    • 从实际的角度来看,您似乎已经解决了您的问题。如果您对垃圾收集感到好奇,请阅读。这是一个需要时间的过程,因此如果这种情况发生得过于频繁,那么限制您的记忆可能会损害您的表现。
    • 非常感谢您的回答。这很有帮助!
    【解决方案3】:

    1) 是的,您的可用内存较少,

    2) 通常设置内存大小以适应程序。

    3) 找出最佳尺寸的最佳方法是用实际工作量测试您的程序。

    4) 是的,有时很少,有时很多。这取决于你在做什么。如果您需要节省内存,您可能会发现这是值得的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-26
      • 2014-02-24
      • 2021-07-19
      • 2012-09-13
      • 2014-07-20
      • 2012-11-04
      相关资源
      最近更新 更多