首页 文章

如何确保JVM以Xms的值启动

提问于
浏览 179 次
3

当我运行一个初始堆大小为3G的java程序(由-Xms3072m VM参数设置)时,JVM不会以该大小启动 . 它以400米左右开始,然后根据需要继续获取更多内存 .

这对我来说是一个严重的问题 . 我知道JVM在一段时间后需要上述金额 . 当JVM根据需要增加其内存时,它会减慢速度 . 在JVM获取更多内存的时候,垃圾收集花费了大量时间 . 我认为记忆获取是一项昂贵的任务 .

如何确保JVM实际上尊重起始堆大小参数?

Update: 此应用程序创建了大量对象,其中大多数快速死亡 . 一些结果对象需要保留在内存中(从年轻堆中转移出来) . 在此操作期间,所有这些对象都需要在内存中 . 操作完成后,我可以看到年轻堆中的所有对象都被声明成功 . 所以没有内存泄漏 .

当堆大小达到3G时,相同的操作平稳运行 . 这清楚地表明所需的额外时间用于获取内存 .

这个Sun JDK 5 .

4 回答

  • 0

    如果我没有弄错,Java会尝试从操作系统获取内存的预留 . 因此,如果你要求3 GB作为Xms,Java将询问操作系统,如果这是可用的但是不能立即启动所有内存......它甚至可能保留它(不分配它) . 但这些都是细节 .

    通常,JVM在启动严重的旧代垃圾收集之前会运行到Xms大小 . 年轻一代GC一直在运行 . 通常情况下,GC仅在旧的GC运行且VM位于Xms和Xmx之间时才会显着,或者,如果将其设置为相同的值,则大致命中Xmx .

    如果你需要为短期物体提供大量内存,可以通过将年轻区域设置为...来增加该内存区域...让我们说1 GB -XX:NewSize=1g 因为将年轻的"buckets"从年轻的"buckets"移动到老一代是很昂贵的 . 因为如果它还没有变成真正的垃圾,JVM会检查垃圾,找不到任何垃圾,在幸存者空间之间复制,最后进入旧的垃圾箱 . 因此,当你知道你没有任何东西并且以某种方式推迟时,试着压制年轻人的垃圾检查...

    试试看!

  • 2

    我相信你的问题并非来自你的想法 .

    看起来你的成本最高的是GC周期,而不是堆大小的分配 . 如果您确实在创建和删除大量对象 .

    你应该把精力集中在分析上,找出究竟是什么让你付出了太多代价,并努力进行重构 .

    我的预感 - 对象创建和删除,以及GC循环 .

    在任何情况下, -Xms 应该设置最小堆大小(如果它不是Sun,则为 check this with your JVM ) . 仔细检查,看看为什么你认为不是这样 .

  • 3

    我已经使用了太阳的vm,并以最小设置为14演出开始,它确实从那开始 . 也许你应该尝试将xms和xmx值设置为相同的amt,即试试这个-Xms3072m -Xmx3072m

  • 0

    为什么你认为堆分配不对?采用仅显示400米的任何操作系统工具并不意味着它没有被分配 .

    我真的不知道你在追求什么 . 400米及以上是否已成问题,或者您的程序是否需要那么多?如果你真的需要处理那么多的内存,你似乎需要很多对象而不是你可以做几件事:

    如果内存消耗与你的直觉不符,那么它的数量可能比你可能泄漏的内存要多 . 这可以解释为什么它会随着时间的推移“减速” . 也许你错过了从一个结构中删除对象,因此它们不会被垃圾收集,并且正在减慢查找速度 .

    你的记忆设置可能本身就是麻烦 . 垃圾收集本身并不运行 . 只有在达到某个阈值时才会调用它 . 如果你给它一个大堆设置并且你的操作系统有足够的内存,那么垃圾收集不会经常运行 .

    您提到的特征将是创建大量对象的场景,以及在再次删除它们之后不久 . 否则垃圾收集不会成为问题(某种代际gc) . 这意味着你只有“年轻”的对象 . 如果您只需要很短的时间就需要对象,请考虑使用对象池 . 这将完全消除垃圾收集 .

    如果您知道代码中有很多时候运行gc,您可以考虑手动运行它以查看它是否发生了任何变化 . 这就是你需要的

    Runtime r = Runtime.getRuntime();
      r.gc();
    

    这仅用于调试目的 . gc在大多数时间都做得很好,所以不需要自己调用gc .

相关问题