jjzjj

Java CMS GC 行为

coder 2024-03-27 原文

我有一个导致产生大量垃圾的应用程序。第一个(也是几乎一个)标准是低 GC 暂停时间。我使用 visualgc 工具(和 gc 日志)尝试不同的 GC 参数。最佳参数如下。

-XX:+UseConcMarkSweepGC

-Xmx1172M

-Xms600M

-XX:+UseParNewGC

-XX:NewSize=150M

我的应用程序在 Java 1.6.0_21 的 SunOS 10 上运行。硬件是 2 x CPU 四核(uname -X 结果是 numCPU = 8)。

问题是

观察 GC 行为,在伊甸园空间创建新对象,直到伊甸园已满。当 eden space full GC 运行时,清除垃圾,如果对象不是死副本到 Old-gen(我丢弃 'from' & 'to' 空间),同样 Old-Gen 已满,GC 以 CMS 并发阶段运行并清除 Old -创空间。 CMS 的某些部分是 Stop-the-world(暂停时间)。这是一个循环。

  1. 以上情况是否属实?
  2. GC清理老年代空间后,没有足够的空间扩展老年代空间(XMS和XMS值不同)?
  3. full GC 操作何时开始?如何决定?
  4. CMS-concurrent 阶段持续时间取决于 Eden 空间大小,实际上我的预期是,Eden 空间不会影响 CMS-concurrent 阶段持续时间。 CMS 并发阶段与 eden 空间相关的 GC 发生了什么?
  5. 还有什么建议可以让我尽量减少停顿时间?的确,对我来说最有值(value)的答案:)

谢谢

最佳答案

在使用 CMS 时,您不能只忽略幸存者空间。 CMS 不是一个压缩收集器,这意味着如果你(或 JVM)得到了错误的 tenuring 阈值,那么你将慢慢地将对象渗入 tenured,这将增加 tenured 碎片的速率,这将提前 CMS 被强制的时间,因为它没有足够的连续可用空间来处理从幸存者空间到终身空间的晋升,这将强制执行完整的 gc 循环,而没有预先警告,因此这是 1 STW 暂停中的全部内容。这需要多长时间取决于堆的大小,但有一点很有可能,它将比普通的伊甸园集合长几个数量级。

这里还有一些需要注意的地方;

  1. STW 停顿不仅来自 CMS,它们也来自年轻代收集器
  2. CMS 有 2 个 STW 阶段(标记和备注)和 3-4 个并发阶段,第一个 STW 阶段(标记)严格是单线程的,这可能会导致问题(对此 here 的示例讨论)
  3. 您可以控制处理并发阶段的线程数
  4. 您需要了解对象的生存时间,这可能意味着使用 -XX:+PrintTenuringDistribution 或者您可以像之前那样用 visualgc 观察它
  5. 然后,您可以使用 -XX:SurvivorRatio 来调整它,以控制相对于伊甸园的幸存者空间的大小,并使用 -XX:MaxTenuringThreshold 来控制对象可以执行的频率在一个年轻的 Collection 品被终身使用之前幸存下来
  6. -XX:CMSInitiatingOccupancyFraction 可用于指导 CMS 在开始 CMS 阶段之前它需要多满(弄错了,你会严重暂停)

最终,您需要了解暂停的是哪个收集器、暂停频率、暂停时间以及暂停是否有任何异常原因。然后,您需要将其与每一代的大小进行比较,以查看是否可以调整参数以最大程度地减少暂停次数(和/或持续时间)。

请记住,由于需要长时间运行测试以查看它是否会随着时间的推移而恶化,因此这可能会耗费大量时间。此外,如果没有可重复的自动化工作负载,几乎不可能得出任何关于您是否真正改进了事情的确切结论。

内部摘要信息的一个很好来源是 Jon Masamitsu's blog .另一个很好的介绍是 GC Tuning in the HotSpot Java VM .

关于Java CMS GC 行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5322761/

有关Java CMS GC 行为的更多相关文章

  1. ruby - 如何根据特征实现 FactoryGirl 的条件行为 - 2

    我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden

  2. ruby - Ruby gsub 替换中的行为不一致? - 2

    两个gsub产生不同的结果。谁能解释一下为什么?代码也可在https://gist.github.com/franklsf95/6c0f8938f28706b5644d获得.ver=9999str="\tCFBundleDevelopmentRegion\n\ten\n\tCFBundleVersion\n\t0.1.190\n\tAppID\n\t000000000000000"putsstr.gsub/(CFBundleVersion\n\t.*\.).*()/,"#{$1}#{ver}#{$2}"puts'--------'putsstr.gsub/(CFBundleVersio

  3. ruby-on-rails - Ruby 中意外的大小写行为 - 2

    我在一段非常简单的代码(如我所想)中得到了一个错误的值:org=4caseorgwhenorg=4val='H'endputsval=>nil请不要生气,我希望我错过了一些非常明显的东西,但我真的想不通。谢谢。 最佳答案 这是典型的Ruby错误。case有两种被调用的方法,一种是你传递一个东西作为分支的基础,另一种是你不传递的东西。如果您确实在case中指定了一个表达式语句然后评估所有其他条件并与===进行比较.在这种情况下org评估为false和org===false显然不是真的。所有其他情况也是如此,它们要么是真的,要么是假的。

  4. ruby - 使对象的行为类似于 ruby​​ 中并行分配的数组 - 2

    假设您在Ruby中执行此操作:ar=[1,2]x,y=ar然后,x==1和y==2。是否有一种方法可以在我自己的类中定义,从而产生相同的效果?例如rb=AllYourCode.newx,y=rb到目前为止,对于这样的赋值,我所能做的就是使x==rb和y=nil。Python有这样一个特性:>>>classFoo:...def__iter__(self):...returniter([1,2])...>>>x,y=Foo()>>>x1>>>y2 最佳答案 是的。定义#to_ary。这将使您的对象被视为要分配的数组。irb>o=Obje

  5. ruby - 了解在 Ruby 中与 lambda 一起使用的 inject 行为 - 2

    我经常将预配置的lambda插入可枚举的方法中,例如“map”、“select”等。但是“注入(inject)”的行为似乎有所不同。例如与mult4=lambda{|item|item*4}然后(5..10).map&mult4给我[20,24,28,32,36,40]但是,如果我制作一个2参数lambda用于像这样的注入(inject),multL=lambda{|product,n|product*n}我想说(5..10).inject(2)&multL因为“inject”有一个可选的单个初始值参数,但这给了我......irb(main):027:0>(5..10).inject

  6. ruby - 奇怪的 ruby​​ for 循环行为(为什么这样做有效) - 2

    defreverse(ary)result=[]forresult[0,0]inaryendresultendassert_equal["baz","bar","foo"],reverse(["foo","bar","baz"])这行得通,我想了解原因。有什么解释吗? 最佳答案 如果我使用each而不是for/in重写它,它看起来像这样:defreverse(ary)result=[]#forresult[0,0]inaryary.eachdo|item|result[0,0]=itemendresultendforainb基本上就

  7. ruby - 比较 rspec 中的 float 时的奇怪行为 - 2

    以下测试中的第3个失败:specify{(0.6*2).shouldeql(1.2)}specify{(0.3*3).shouldeql(0.3*3)}specify{(0.3*3).shouldeql(0.9)}#thisonefails这是为什么呢?这是浮点问题还是ruby​​或rspec问题? 最佳答案 从rspec-2.1开始specify{(0.6*2).shouldbe_within(0.01).of(1.2)}在那之前:specify{(0.6*2).shouldbe_close(1.2,0.01)}

  8. ruby - 为什么 `Symbol#match` 的行为与 `String#match` 和 `Regexp#match` 不同? - 2

    String#match和Regexp#match在匹配成功时返回一个MatchData:"".match(//)#=>#//.match("")#=>#//.match(:"")#=>#但是Symbol#match返回匹配位置(如String#=~)::"".match(//)#=>0为什么Symbol#match表现不同?有用例吗? 最佳答案 我将其报告为Ruby核心中的错误:https://bugs.ruby-lang.org/issues/11991.让我们看看他们会怎么说。更新被质疑的行为似乎是一个错误。似乎从Ruby2.

  9. ruby - Rails 3 应用程序的 respond_with 语法有奇怪的行为吗? - 2

    在为提供json的Rails3.0.3应用构建API时,发生了一些意外行为。以下是Controller。问题是关于respond_with。我已经在应用程序Controller中有respond_to:json。createAction正常运行,创建后数据也被发回。但是更新操作的respond_with不会发回任何数据。响应主体为空白。defcreateline=get_lineinput_header=line.input_headers.create(params[:input_header])respond_with(input_header,:location=>api_v1_

  10. arrays - 数组元素赋值的奇怪行为 - 2

    今天我遇到了数组元素赋值的一些奇怪行为:arr=["a","b"]arr2=[1,2]arr.unshift(arr2)#=[[1,2],"a","b"]arr.push(arr2)#=>["a","b",[1,2]]但是,这是有道理的:arr[0,0]=arr2#=>[1,2,"a","b"]我知道在[0,0]中,第一个零是index,第二个是该数组中从index开始的元素数。在我看来它应该与unshift相同,但事实并非如此。谁能解释一下这种行为? 最佳答案 如果我们diveintotherubysourcecode,我们会找到

随机推荐