感觉写的不错,G1在未来两三年肯定慢慢占据主流,多学习学习:

开源搜索引擎Solr是一款非常优秀的搜素引擎,只要一些简单的配置就能进行使用,大大减少了开发时间。

在我工作的环境中,整站的商品搜索业务都是依托于Solr,在Solr的使用上沉淀了不少宝贵的开发经验。随着公司商品数据规模不断的扩大,针对Solr的二次开发难度也在不断的增大,在过去的几年时间内,我把大量的数据放在索引构建上,从之前的DB模式24小时都无法完成全量的构建,到现在使用hive + avro + mapreduce把全量构建压缩到3小时以内,从之前的DB增量模式经常出现更新失败,更新延迟,到现在使用kafka+redis的模式保证更新数据不丢实,更新的延迟在1分钟以内。整个全量增量的索引架构都是可以横向扩展。

在索引构建告一段落后,查询又出现了问题,经常可以看到Solr每隔20分钟,会有timeout情况的出现。查看了下日志,在那段报错的时间段,正好是slave从master上获取增量数据的时间(replication配置了每隔20分钟slave replication一次数据到master),而Solr中许多内置的缓存都开的比较大。当数据更新后,Solr会对Cache进行重新的预热,在这个时候,有大量的内存对象会被换入换出,可能在这个点触发了full gc。

为了验证是否是full gc的可能,首先第一步获取full的信息,命令:

使用lsof命令根据端口找出pid(当然linux有很多其他方式,条条大路通罗马),然后使用jstat -gc命令获取信息。图中该Solr程序已经运行了196hrs35min,可以看出FGC一共执行了356次,一共花费6331s,平均一次停顿18s,这种停顿在java中有个专有名词——stop the world(STW),顾名思义在这18秒内,所有的业务代码都会stop给GC让出资源。结合程序启动的时间,平均每30分钟有一次18秒的卡顿,无论solr本身的性能再优越18秒足以让client time,问题也就这样终于被发现了。

由于Solr进程没有进行full gc的制定,所以都是java6的默认配置,java6默认的配置对于Solr这种低延迟的场景显然是不适用的,所以需要选择一款合适的GC。GC的两大标准:吞吐量 & 响应时间。就service来说,响应时间优先级要高于吞吐量,对于上述的垃圾回收而言,串行垃圾回收和并行垃圾回收不适合service的场景,对于CMS和G1,虽然都是以响应时间优先,但是在内部实现上差异很大,G1是oracle唯一还在继续开发优化的垃圾回收器,支持并发并行操作,在保证响应时间的前提下,尽可能的提高了吞吐量,所以更建议对于大型service服务使用G1作为默认的垃圾回收。由于G1在jdk6上还是个不稳定的版本,所以需要将JDK升到7.4以上。

关于G1的介绍有很多,就不介绍了,主要介绍下调优的一些思路

1. 请打开gc log日志

gc log日志在gc调优的过程中非常关键,很多参数的调整都需要以gc log日志的反馈作为根据,从而判断参数是否生效。
     参数:-XX:+PrintGC -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintAdaptiveSizePolicy -Xloggc:./gc.log

2. 根据gc日志的返回,找到full gc的原因

从上述的GC信息中可以看到,是因为无法分配内存导致FGC的触发。在这里先简答介绍下G1的模型,G1和其他GC算法不同的是,G1使用region把内存分为多块,每个region的大小可以根据-XX:G1HeapGegionSize进行设置,最大不超过32m,每个region有唯一一个角色(unused,young,old),由于Solr需要大量的内存作为cache,所以我将该值设置为最大,即:-XX:G1HeapGegionSize=32m,G1当要为对象申请内存空间的时候,回去region列表中找合适的region进行分配,但是这里有个特殊的场景,当一个内存对象很大,大到一个region无法满足之后,G1会查找一片连续的region用于存放该对象,并且这些region标记为old,跳过young gc。在G1算法内,如果一个对象超过了region的1/2,就认为是一个大对象。再回到上面的日志可以发现,Solr需要申请1个G的内存空间,而由于region的大小为32M,即需要32个连续的region。但是我从内存的使用上来看,申请了100G的内存,实际只使用了30G就出现了这种场景,原因是g1内存分配不适连续分配,导致内存碎片,所以即使还有很多余量,但是无法找到32个连续的region,导致强制执行了fgc。找到了根本原因后就简单了。

3. 参数调整

G1对内存的压缩只在两种情况下进行,第一个中情况是fgc,这种事我们应该尽力避免的,第二种是在初始话标记阶段,所以调优的目标是希望能在适当的时间触发该阶段。在补充了G1的整个执行周期,G1首先上来进行young gc,会清理一部分内存数据,把旧的数据迁移到old region,随着内存不断的增加,每次做完一次young gc后,会根据-XX:InitiatingHeapOccupancyPercent判断是否需要进入初始化标记阶段,所以这个参数在G1大对象调优上非常关键,我最后调整为:-XX:InitiatingHeapOccupancyPercent=30,即到达最大内存的30%开始执行初始化标记。当完成标记后,会进行clean up在clean up阶段old区域的内存会被回收压缩,达到目的。在后面会进入mixed gc,反复执行多次满足条件后再返回到young gc,一个周期就这么完成了。

当然还有很多参数的调整没有给出,但是我觉得还是希望大家自己去研究,很多参数的调整需要针对特殊的业务,千万不可生搬硬套。最后的调整也起到了非常好的效果,从一天上万的报错降低到100个以内,也得到了CTO和其他老大们的肯定。

参考资料

https://blogs.oracle.com/g1gc/entry/g1gc_logs_how_to_print

http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/G1GettingStarted/index.html

https://software.intel.com/en-us/blogs/2014/06/18/part-1-tuning-java-garbage-collection-for-hbase

http://www.oracle.com/technetwork/cn/community/developer-day/2-jdk7-g1-2083344-zhs.pdf
--------------------- 
作者:github_26340097 
来源:CSDN 
原文:https://blog.csdn.net/github_26340097/article/details/51120026 
版权声明:本文为博主原创文章,转载请附上博文链接!

转载一条G1垃圾回收器的调优经验相关推荐

  1. JVM垃圾回收器和调优

    回顾 什么是GC? 找到垃圾,并且回收,让这块内存重新可用. Java的GC算法是根搜索算法,可以作为GCRoot的对象有 线程栈变量 静态变量 常量池 JNI指针 回收的算法有: 标记清除 标记整理 ...

  2. G1垃圾回收器在并发场景调优

    一.序言 目前企业级主流使用的Java版本是8,垃圾回收器支持手动修改为G1,G1垃圾回收器是Java 11的默认设置,因此G1垃圾回收器可以用很长时间,现阶段垃圾回收器优化意味着针对G1垃圾回收器优 ...

  3. jvm性能调优 - 21案例实战_百万级用户的在线系统如何基于G1垃圾回收器优化性能

    文章目录 案例背景引入 系统核心业务流程分析 系统的运行压力 G1垃圾回收器的默认内存布局 GC停顿时间如何设置? 到底多长时间会触发新生代GC? 新生代gc如何优化? mixed gc如何优化? 案 ...

  4. jvm性能调优 - 18白话G1垃圾回收器的工作原理

    文章目录 ParNew + CMS的组合的痛点 G1垃圾回收器 G1是如何做到对垃圾回收导致的系统停顿可控的? Region可能属于新生代也可能属于老年代 总结 ParNew + CMS的组合的痛点 ...

  5. CMS垃圾回收器和G1垃圾回收器区别

    1.引言 我们知道java在C++语言的基础上演变而来.java垃圾回收机制是java和C++等语言的一个重要区别,让java程序员可以不用像C++程序员那样为内存回收而提心吊胆,而是专注于业务逻辑. ...

  6. G1垃圾回收器详细解读

    最新的 G1 垃圾回收器 目录结构 1.G1垃圾回收器概述 2.设定内存大小 3.新生代垃圾回收 4.老年代垃圾回收 5.大对象回收分配策略 6. 混合垃圾回收 (Mixed-GC) 7. 总结 Pa ...

  7. 一文搞懂G1垃圾回收器

    G1是从JDK9之后的默认垃圾回收器,其功能强大,性能优异,不过目前市面的材料不算多,很多都是抄来抄去,讲得也不太清楚.经过仔细阅读oracle官网以及相关的材料,从整体上梳理了G1的过程,希望这一文 ...

  8. 垃圾回收器之 G1 垃圾回收器

    4.4 G1 定义:Garbage First 2004论文发布 2009 JDK 6u14 体验 2012 JDK 7u4 官方支持 2019 JDK9 默认 (废弃了之前的 CMS 垃圾回收器) ...

  9. G1 垃圾回收器实现细节

    一直惦记着G1垃圾回收器,如果不出意外的话,G1今后一定会被大量用于生产. 之前零零散散的看了一些关于G1的知识点,但是很难形成一个知识体系,都只是皮毛.趁着这个假期的尾巴,恶狠狠的啃了一遍谷歌出来的 ...

最新文章

  1. 2022-2028年中国灭火装置行业市场前瞻与投资战略规划分析报告
  2. linux top cpu核数查看,Linux怎么查看CPU核数?
  3. 苹果内购和 Apple Pay
  4. 【计算机网络】HTTP 与 HTTPS ( HTTPS 简介 | HTTP 通信过程 )
  5. mysql freebuf_浅析mysql存储过程
  6. to_number用法示例_Number()函数以及JavaScript中的示例
  7. nasdocker推荐,附小技巧
  8. Silverlight安装相关问题
  9. 林阳斌集美大学计算机学院,集美大学计算机工程学院导师教师师资介绍简介-林阳斌副教授(2021.04.06)...
  10. vc6.0快捷键小结收藏
  11. appium环境搭建android版,【appium】自动化测试appium教程(环境搭建上)
  12. 软件测试缺陷报告的5c标准
  13. 树莓派系统安装和调试 总结整理篇
  14. 混合正弦余弦算法和Lévy飞行的麻雀算法
  15. uniapp地图轨迹回放
  16. u盘数据恢复,教你轻松搞定!
  17. 日月光华深度学习(五)--卫星图像识别tf.data、卷积综合实例
  18. Mobius反演(莫比乌斯反演)
  19. 【matplotlib】20.其他图
  20. 三洋服务器显示F6,三洋空调故障代码有哪些?

热门文章

  1. Visual Studio Community 2017/2019下载链接
  2. lxml库的基本使用
  3. android-Excel表的操作 - 随心
  4. C语言中求π(pi)的方法
  5. 流控制(RTS/CTS/DTR/DSR )
  6. 游戏开发之U3D实现技能图标冷却的效果
  7. SDU项目实训——同态加密技术学习
  8. 1990-2021年全国各省城市化水平数据
  9. indesign选中不了图片删除_有办法了!批量删除多个Word页眉页脚
  10. UnitTest 框架