Java的非常大的堆大小[关闭]Java的非常大的堆大小[关闭](Java very large h

2019-05-12 16:59发布

有没有人有在Java中使用非常大的堆,12 GB或更高的经验?

  • 是否GC使程序无法使用?
  • 你用什么GC PARAMS?
  • 哪种JVM,太阳或BEA会更适合这个?
  • 哪个平台,Linux或Windows,执行这样的条件下更好?
  • 在Windows的情况下,会出现这样高的内存负载下64位Vista和XP之间进行过任何性能差异?

Answer 1:

如果您的应用程序不是交互式的,并且GC暂停是不是你的问题,不应该有任何问题了64位Java来处理非常大的堆,甚至达数百GB的的。 我们还没有注意到的是Windows或Linux的稳定性问题。

但是,当你需要保持GC暂停低,事情就真的讨厌:

  1. 忘了默认的吞吐量,停止这世界GC。 这将暂停你申请的秒温和堆(<〜30 GB)和几分钟路数(>〜30 GB)几十。 和购买更快的DIMM也无济于事。

  2. 最好的办法可能是CMS收集器,由-XX启用:+ UseConcMarkSweepGC。 在CMS垃圾收集器仅用于初始标记阶段和重写相停止应用程序。 对于像<4 GB非常小堆,这通常是没有问题的,但是对于产生大量垃圾和一大堆的应用,重标记阶段可能需要相当长的时间 - 通常是那么句号这世界少得多,但仍然可以非常大堆问题。

  3. 当CMS垃圾收集不够快年老代填满前完成操作,回落到标准停止的世界GC。 期望〜30个或更多的第二长的停顿为尺寸16 GB的堆。 你可以尽量避免这种让你的应用的长寿命垃圾产生率尽可能低。 需要注意的是运行内核的数量越高你的应用,更大的越来越此问题,因为CMS利用只有一个核心。 显然,提防难保的CMS不回退到STW收集器。 而当它,它通常发生在高峰负荷,而应用程序是死了几秒钟。 你可能不希望签署SLA对于这样的配置。

  4. 嗯,有新的G1的事情。 从理论上设计,以避免与CMS的问题,但我们已经尝试过了,并指出:

    • 其吞吐量比CMS差。
    • 它理论上应该避免首收集的内存块受欢迎,但它很快就到达那里几乎所有的块是“流行”的状态,它是基于假设简单地停止工作。
    • 最后,停止了世界的后备仍然存在G1; 问甲骨文,当假设代码运行。 如果他们说“从来没有”,问他们,为什么代码是存在的。 因此,恕我直言,G1确实没有使Java的巨大堆问题消失,只会使得它(可以说)稍小一点。
  5. 如果你有雄鹿大内存大的服务器,你有一个良好的,商用类硬件产品可能还块钱加快,pauseless GC技术,如通过阿祖尔提供的一个。 我们有自己的384 GB RAM的服务器之一,它确实工作得很好 - 没有暂停,停止这世界的代码在GC 0线。

  6. 编写应用程序的一部分该死需要大量内存在C ++中,像LinkedIn社交图形处理一样。 你还是不会避免这样做(如堆碎片)中的所有问题,但它会肯定更容易保持暂停低。



Answer 2:

我Azul系统的CEO,所以我在我的关于这一主题的意见很明显的偏见! :) 话虽如此...

Azul公司的CTO,吉尔·特内,有垃圾收集,并在他的各种解决方案的审查相关的问题很好的概述了解Java垃圾收集,哪些是你可以做的介绍,并有这篇文章中的其他细节: HTTP:// www.infoq.com/articles/azul_gc_in_detail 。

我们诚JVM Azul的C4垃圾收集器是并行和并发,并使用相同的GC机制,同时为新老两代,同时工作在两种情况下压实。 最重要的是,C4没有停止的世界回落。 所有的压实与运行的应用程序同时进行。 我们的客户运行非常大(数百GB的)<10毫秒的最坏情况GC暂停时间,并根据不同的应用往往时间少于1-2毫秒。

与CMS和G1的问题是,在某些时候Java堆内存必须夯实,而这两个垃圾收集器的停止这世界/ STW(即暂停应用程序)进行压缩。 因此,尽管CMS和G1可以推出STW暂停,并不能消除它们。 Azul的C4,然而,这完全消除STW暂停,这就是为什么诚有如此低的GC暂停甚至是巨大的堆大小。



Answer 3:

我们有我们分配12-16 GB的应用程序,但它确实只是正常工作期间达到8-10。 我们使用Sun JVM(IBM的尝试,这是一个有点一场灾难,但对我们而言,仅仅可能是无知,我有一个由它发誓朋友 - 在IBM的工作)。 只要你给你的应用程序喘息的空间,JVM可以处理大型堆的大小与没有太多的GC。 的“额外”的内存充足是关键。
Linux是几乎总是比Windows更稳定,当它不是稳定它是一个更容易地狱找出原因。 。Solaris是坚如磐石,以及和你的DTrace太:)有了这几样的负载,为什么地球上,你会是使用Vista或XP? 你只是在自找麻烦。 我们不做任何幻想与GC PARAMS。 我们设定的最小分配等于最大值,使得它不会不断尝试调整,但就是这样。



Answer 4:

我已经分别使用Sun JVM 1.6的64位版本(显然)在Linux和Solaris下的两个不同的应用60个GB堆大小使用。

我从来没有遇到过与基于Linux的应用程序的垃圾收集问题,附近堆大小限制推升时除外。 为了避免固有的那种情况下的抖动问题(太多的时间花在垃圾收集),我只是优化的内存使用量在整个程序,以便使用高峰是低于64 GB堆大小限制约5-10%。

在Solaris下运行不同的应用程序,但是,我遇到这使得有必要做大量的调整的显著垃圾回收问题。 这主要包括三个步骤:

  1. 使能/迫使使用平行垃圾收集器的经由-XX:+ UseParallelGC -XX:+ UseParallelOldGC JVM选项,以及控制经由-XX使用GC线程数:ParallelGCThreads选项。 请参阅“ Java SE 6的HotSpot虚拟机垃圾收集调优 ”的更多细节。

  2. 局部变量为“空”,他们不再需要经过广泛而看似荒谬的设置。 这些大多是应该的范围外出后一直符合垃圾回收的变量,因为引用未复制他们没有内存泄漏的情况。 但是,这种“手把手”的策略,以帮助垃圾收集被莫名其妙地需要出于某种原因对Solaris平台的问题在此应用。

  3. 选择性地使用临时对象分配的广泛周期之后在键代码段的System.gc()的方法调用。 我知道反对使用这些调用标准的警告,和说法,他们通常应该是不必要的,但我发现他们在这运行内存密集型应用程序时,驯兽垃圾回收的关键。

上述三个步骤制备是可行的,保持包含,并在约60 GB堆使用高效运行,而不是生长出控制了进入128 GB堆大小限制,这是代替这种应用。 特别是并行的垃圾收集器是非常有益的,因为当存在大量的对象,即,用于主要垃圾收集所需要的时间是在堆中的对象的数目的函数主要垃圾收集周期是昂贵的。

我不能在这个规模上其他特定于平台的问题发表评论,也没有我用非Sun(甲骨文)的JVM。



Answer 5:

12GB应该是一个体面的JVM实现,如Sun的Hotspot没有问题。 我会建议你使用并发标记和清除colllector(-XX:+ UseConcMarkSweepGC)使用的是Sun VM.Otherwies时,你可能会面临漫长的“停止世界”的阶段,是所有线程都为GC时停止。

操作系统不应该对GC的性能有很大的区别。

您将需要当然是一个64位操作系统以及一台具有足够的物理内存。



Answer 6:

我还建议考虑采取堆转储,看看内存的使用可以在你的应用程序加以改进和分析的东西转储比如Eclipse的MAT 。 有在寻找内存泄漏入门的MAT页上的几篇文章。 您可以使用JMAP获得的东西转储,如...

jmap -heap:format=b pid


Answer 7:

正如上面提到的,如果你有一个非交互式程序,默认(压缩)垃圾收集器(GC)应该很好地工作。 如果你有一个互动节目,而你(1)不要快于GC能跟上分配内存,和(2)不创建临时对象(或对象的集合)是太大(相对于总最大JVM内存)的GC来解决,那么CMS是给你的。

如果你有一个互动节目,其中GC没有足够的喘息空间,你遇到了麻烦。 这是真实的,无论你有多少内存,但你有更多的内存,坏它得到。 这是因为当你太内存不足,CMS将耗尽内存,而直到所有的记忆已被检查垃圾压实选区(包括G1)将暂停一切。 该停止的世界暂停变大,你有更多的内存。 相信我,你不想让你的servlet来暂停超过一分钟。 我写了关于G1这些暂停了详细的StackOverflow的答案。

从那时起,我公司已切换到Azul的诚。 它仍然不能处理您的应用程序确实需要更多的内存比你已经有了,但直到这一刻它运行像做梦一样的情况。

但是,当然,诚是不是免费的,其特殊的酱专利。 如果你有比金钱更多的时间,请尝试重写你的应用程序使用的JVM集群。

在地平线上,甲骨文正在对多技嘉堆高性能GC。 然而,截至今日,这不是一个选项。



Answer 8:

如果切换到64位,你会使用更多的内存。 指针变成8个字节,而不是4.如果要创建大量的对象这可以明显的看到,因为每一个对象的引用(指针)。

使用Sun JVM 1.6没有问题,我最近分配的内存15GB Java编写的。 虽然它是所有只分配一次。 没有更多的内存分配或初始确认金额后释放。 这是在Linux,但我想象中的太阳JVM将工作一样在64位Windows。



Answer 9:

从太阳在Java 6的文章可以帮助你: http://java.sun.com/developer/technicalArticles/javase/troubleshoot/



Answer 10:

你应该试着对你的应用程序运行visualgc的。 It'sa堆可视化工具that's的jvmstat下载的一部分在http://java.sun.com/performance/jvmstat/

它比读书GC日志轻松很多。

它可以快速帮助您了解如何堆的部分(一代)的工作。 当你的整个堆可能是10GB,堆的不同部分会小很多。 选区在堆的伊甸部相对便宜,而在老一代充分的GC是昂贵的。 调整您的堆,使得伊甸园大和老一代几乎没有碰过是一个很好的策略。 这可能会导致非常大的整体堆中,但究竟发生了什么,如果JVM从不接触页面,it's只是一个虚拟的网页,并doesn't有占用内存。



Answer 11:

几年前,我比较JRockit的和太阳JVM的12G堆。 JRockit的赢了,和Linux大页面支持,使我们的试运行快20%。 YMMV作为我们的测试是非常处理器/存储密集和主要是单线程。



Answer 12:

这里的一对GC的文章从Java冠军之一- http://kirk.blog-city.com/is_your_concurrent_collector_failing_you.htm

柯克,作者写道:“给我你的GC日志

我目前在研究太阳JVM产生GC日志感兴趣。 由于这些日志不包含任何商业培训相关的信息,应当减轻对保护proriatary信息的担忧。 我想问的是与日志你提到的操作系统,完整的版本信息JRE和任何堆/ gc的相关命令行开关已设置。 我也想知道,如果你正在运行的Grails / Groovey,JRuby的,斯卡拉或大于或沿端Java以外的东西。 最佳设置是-Xloggc :. 请注意,当它达到你的OS大小限制这个日志不会翻身。 如果我发现什么有趣的东西,我会很乐意给你一个回报非常快的概要。 “



Answer 13:

最大内存XP可以解决的是4演出( 在这里 )。 所以,你可能不希望使用XP为(使用64位操作系统)。



Answer 14:

虽然安腾不是一个受欢迎的目的地太阳已经拥有一段时间的Itanium 64位JVM。 在Solaris和Linux 64位JVM应该是你应该追求的。
一些问题

1)为您的应用程序是否稳定?
2)你已经测试了32位JVM的应用程序?
3)是确定在同一机器上运行多个JVM?

我希望从Windows 64位操作系统获取稳定在大约一年左右,但在那之前,Solaris / Linux操作系统可能是更好的选择。



文章来源: Java very large heap sizes [closed]