我最近发布了一个关于提高内存使用率/GC的问题,并且已经能够使用MinitByteString
s将内存消耗降低到我认为是适当/成比例的水平(并且在此过程中从“从未完成”到当前测试的“非常非常慢”),但似乎仍然存在我认为GC时间过多的问题。
在以下输出中分析测试结果:
49,463,229,848 bytes allocated in the heap 68,551,129,400 bytes copied during GC 212,535,336 bytes maximum residency (500 sample(s)) 3,739,704 bytes maximum slop 602 MB total memory in use (0 MB lost due to fragmentation) Tot time (elapsed) Avg pause Max pause Gen 0 14503 colls, 0 par 1.529s 1.681s 0.0001s 0.0164s Gen 1 500 colls, 0 par 79.202s 79.839s 0.1597s 0.3113s TASKS: 3 (1 bound, 2 peak workers (2 total), using -N1) SPARKS: 0 (0 converted, 0 overflowed, 0 dud, 0 GC'd, 0 fizzled) INIT time 0.000s ( 0.001s elapsed) MUT time 29.500s ( 82.361s elapsed) GC time 47.253s ( 47.983s elapsed) RP time 0.000s ( 0.000s elapsed) PROF time 33.478s ( 33.537s elapsed) EXIT time 0.000s ( 0.025s elapsed) Total time 110.324s (130.372s elapsed) Alloc rate 1,676,731,643 bytes per MUT second Productivity 26.8% of total user, 22.7% of total elapsed gc_alloc_block_sync: 0 whitehole_spin: 0 gen[0].sync: 0 gen[1].sync: 0
以及以下堆可视化:
目前,我使用的是H,这似乎很有帮助,并尝试了增加线程、世代、因子和使用压缩(N-G-F-c)的组合,所有这些都没有导致性能的明显变化或降低。很明显,一切都是长期存在的(当我增加G时,gen 1的统计数据基本上移动到了最古老的一代,它和gen 0之间没有任何区别),但我不明白为什么GC不能“置之不理”。据我所知,我认为GC只在分配空间不足时运行,但增加分配/因子/堆似乎没有效果。
为了减少GC工作量,我还可以尝试其他任何方法吗?或者有什么方法可以让我知道我的代码存在根本问题,导致这次无法减少?我相信我必须在内存中构建一个大型数据结构,目前是ST
中可变向量的哈希表。我唯一的另一个想法是,在内部我的数据结构被[不必要地?]复制并强制GC运行,但我使用ST
希望避免这种行为。
我还没有看过你的代码,所以你应该把它作为一个扩展注释,而不是一个答案。如您所说,如果您必须构建一个非常大的结构,那么您可以做两件事来限制性能影响:
第一个也是最简单的(但不容易!)步骤是尽可能减少指针。一个巨大的HashMap
可能比一个由未装箱向量支持和索引的巨大哈希表更昂贵。未装箱的东西永远不需要被GC跟踪,这是一个巨大的优势,但它们仍然会被它复制。您可能会发现这是可以接受的,因为复制大型连续向量应该非常便宜。
下一步是通过将内容放入固定内存来隐藏垃圾收集器。我相信标准的(不是很小的)ByteString以及通过外部函数接口创建的数组都可以做到这一点。
框架:Spring+mybatis+dubbo+RocketMQ。 下面是JVM参数: -server-xmx5g-xms5g-xn1g-xx:metaspacesize=512m-xx:maxmetaspacesize=512m-xss256k-xx:survivorratio=8-xx:+printgcdetails-xloggc:/opt/apps/logs/gc.log-xx:+print
问题内容: 在JSF中减小viewstate隐藏字段大小的最佳方法是什么?我已经注意到,我的视图状态大约为40k,这会下降到客户端,并在每次请求和响应(尤其是到达服务器)时都返回到服务器,这对于用户来说是一个严重的问题。 我的环境JSF 1.2,MyFaces,Tomcat,战斧,RichFaces 问题答案: 您是否尝试过将状态保存设置为服务器?这应该仅将ID发送给客户端,并在服务器上保持完整状
我看到最后一个android sdk中有一个更新,他们显示,他们记录了每个事件的参数,但是我如何添加屏幕跟踪? 仪表板中有一个用户参与度选项卡,但该选项卡不会展开以提供更多见解。 但是,我在切换活动时看到这样的消息: D/FA:记录事件(FE):_e,束[{_o=auto,_et=4807,_sc=MainActivity,_si=-3289793799694080660}] 这是什么意思?他们在
问题内容: 如果在这样的调用中收到NullPointerException: 我得到了一个无用的异常文本,例如: 我发现很难找出哪个调用实际上返回了null,经常发现自己将代码重构为如下形式: 然后等待更具描述性的NullPointerException,该异常告诉我要查找的行。 你们中的某些人可能会认为,连接吸气剂是不好的风格,无论如何都应避免,但是我的问题是:我可以在不更改代码的情况下找到错误
问题内容: 在程序快要结束时,我希望将类的所有实例中的特定变量加载到字典中。 例如: 假设实例数量会有所不同,我希望将Foo()的每个实例的x dict加载到新的dict中。我该怎么办? 我在SO中看到的示例假定一个已经具有实例列表。 问题答案: 跟踪实例的一种方法是使用类变量: 在程序结束时,您可以像下面这样创建字典: 只有一个列表: