对于不应暂停超过 200 毫秒的软实时系统的上下文,我们正在寻找一种方法来在 Full GC 即将到来之前发出预先警告。我们意识到我们可能无法避免它,但我们希望在系统停止之前故障转移到另一个节点。
我们已经能够想出一个方案,在即将到来的完整 GC 可能导致系统停顿几秒钟(我们需要避免)之前为我们提供预先警告。
我们能够得出的结果依赖于 CMS 空闲列表统计信息:-XX:PrintFLSStatistics=1。这会在每个 GC 周期后将空闲列表统计信息打印到 GC 日志中,包括年轻的 GC,因此信息在较短的时间间隔内可用,并且在内存分配率较高的时间间隔内会更频繁地出现。就性能而言,它可能会付出一点代价,但我们的工作假设是我们可以负担得起。
日志的输出如下所示:
Statistics for BinaryTreeDictionary:
------------------------------------
Total Free Space: 382153298
Max Chunk Size: 382064598
Number of Blocks: 28
Av. Block Size: 13648332
Tree Height: 8
特别是,最大空闲 block 大小为 382064598 个字。对于 64 位字,这应该略低于 2915MB。这个数字一直在以大约每小时 1MB 的速度非常缓慢地减少。
据我们了解,只要最大空闲 block 大小大于新生代(假设没有大量对象分配),每个对象提升都应该成功。
最近,我们进行了为期几天的压力测试,发现 CMS 能够将最大块大小维持在旧区域总空间的 94% 以上。最大空闲 block 大小似乎正在以小于 1MB/小时的速度减少,这应该没问题——据此我们不会很快达到完全 GC,并且服务器可能会停机以进行更多维护发生频率高于完全 GC。
在之前的测试中,在系统内存效率较低的时候,我们已经能够运行系统长达 10 个小时。在第一个小时内,最大可用 block 大小已降至 100MB,并停留了 8 多个小时。在运行的最后 40 分钟内,最大空闲 block 大小以稳定的速率减小到 0,此时发生了完全 GC——这非常令人鼓舞,因为对于该工作负载,我们似乎能够提前 40 分钟警告(当 block 大小开始稳定下降到 0 时)。
我的问题:假设这一切都反射(reflect)了长时间的峰值工作负载(生产中任何给定时间点的工作负载只会更低),这听起来像是一种有效的方法吗?您认为我们应该能够依赖 GC 日志中的最大空闲 block 大小统计信息的可靠性如何?
我们绝对愿意接受建议,但要求它们仅限于 HotSpot 上可用的解决方案(我们没有 Azul,至少现在是这样)。此外,G1 本身并不是解决方案,除非我们可以提出一个类似的指标,在 Full GC 或任何明显超过我们 SLA 的 GC 之前提前警告我们(这些偶尔会发生)。
最佳答案
我在这里发布了来自 Oracle 的 Jon Masamitsu 的一个非常有启发性和鼓舞人心的答案的相关摘录,我从 HotSpot GC 邮件列表 (hotspot-gc-use@openjdk.java.net) 获得了这个答案——他在 HotSpot 上工作,所以这确实是个好消息。
无论如何,这个问题现在仍然悬而未决(我不能相信自己引用了一封电子邮件:-)),所以请添加您的建议!
格式:引用原帖的缩进比 Jon 的回复更严重。
It is our understanding that so long as the maximum free chunk size is larger than the young generation (assuming no humungous object allocation), every object promotion should succeed.
在很大程度上这是正确的。有情况下 从年轻一代提升到 CMS 一代的对象将需要 CMS 一代比年轻一代有更多的空间。我不 认为这在很大程度上发生了。
以上内容非常令人鼓舞,因为我们绝对可以投入一些备用内存来防止他描述的罕见情况,而且听起来我们在其他情况下会做得很好。
<--截图-->
My question to you: assuming this all reflects a prolonged peak workload (workload at any given point in time in production will only be lower), does this sound like a valid approach? To what degree of reliability do you reckon we should be able to count on the maximum free chunk size statistic from the GC log?
最大空闲 block 大小在 GC 打印时是准确的,但它 在您阅读并做出决定时可能已经过时了。
对于我们的工作负载,此指标非常缓慢呈螺旋式下降,因此一点点陈旧不会伤害我们。
<--截图-->
We are definitely open for suggestions, but request that they be limited to solutions available on HotSpot (No Azul for us, at least for now). Also, G1 by itself is no solution unless we can come up with a similar metric that will give us advance warning before Full GCs, or any GCs that significantly exceed our SLA (and these can occasionally occur).
我认为使用最大可用 block 大小作为您的指标是一个很好的 选择。它非常保守(听起来像你想要的)并且 不受物体大小奇怪混合的影响。
对于 G1,我认为您可以使用完全自由区域的数量。 我不知道它是否打印在当前的任何日志中,但它是 可能是我们维护(或可以轻松维护)的指标。如果数量完全免费 regions 随着时间的推移而减少,这可能预示着 full GC 即将到来。
乔恩
谢谢乔恩!
--截图-->--截图-->关于java - 在 full GC 之前获得预先警告,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16273738/
我试图使用yard记录一些Ruby代码,尽管我所做的正是所描述的here或here#@param[Integer]thenumberoftrials(>=0)#@param[Float]successprobabilityineachtrialdefinitialize(n,p)#initialize...end虽然我仍然得到这个奇怪的错误@paramtaghasunknownparametername:the@paramtaghasunknownparametername:success然后生成的html看起来很奇怪。我称yard为:$yarddoc-mmarkdown我做错了什么?
我正在使用active_admin,我在Rails3应用程序的应用程序中有一个目录管理,其中包含模型和页面的声明。时不时地我也有一个类,当那个类有一个常量时,就像这样:classFooBAR="bar"end然后,我在每个必须在我的Rails应用程序中重新加载一些代码的请求中收到此警告:/Users/pupeno/helloworld/app/admin/billing.rb:12:warning:alreadyinitializedconstantBAR知道发生了什么以及如何避免这些警告吗? 最佳答案 在纯Ruby中:classA
我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/
最近,当我启动我的Rails服务器时,我收到了一长串警告。虽然它不影响我的应用程序,但我想知道如何解决这些警告。我的估计是imagemagick以某种方式被调用了两次?当我在警告前后检查我的git日志时。我想知道如何解决这个问题。-bcrypt-ruby(3.1.2)-better_errors(1.0.1)+bcrypt(3.1.7)+bcrypt-ruby(3.1.5)-bcrypt(>=3.1.3)+better_errors(1.1.0)bcrypt和imagemagick有关系吗?/Users/rbchris/.rbenv/versions/2.0.0-p247/lib/ru
我有一个服务模型/表及其注册表。在表单中,我几乎拥有服务的所有字段,但我想在验证服务对象之前自动设置其中一些值。示例:--服务Controller#创建Action:defcreate@service=Service.new@service_form=ServiceFormObject.new(@service)@service_form.validate(params[:service_form_object])and@service_form.saverespond_with(@service_form,location:admin_services_path)end在验证@ser
我使用的是Firefox版本36.0.1和Selenium-Webdrivergem版本2.45.0。我能够创建Firefox实例,但无法使用脚本继续进行进一步的操作无法在60秒内获得稳定的Firefox连接(127.0.0.1:7055)错误。有人能帮帮我吗? 最佳答案 我遇到了同样的问题。降级到firefoxv33后一切正常。您可以找到旧版本here 关于ruby-无法在60秒内获得稳定的Firefox连接(127.0.0.1:7055),我们在StackOverflow上找到一个类
我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www
简而言之错误:NOTE:Gem::SourceIndex#add_specisdeprecated,useSpecification.add_spec.Itwillberemovedonorafter2011-11-01.Gem::SourceIndex#add_speccalledfrom/opt/local/lib/ruby/site_ruby/1.8/rubygems/source_index.rb:91./opt/local/lib/ruby/gems/1.8/gems/rails-2.3.8/lib/rails/gem_dependency.rb:275:in`==':und
我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我
什么是ruby的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht