看看人家那后端API接口写得,那叫一个优雅!.docxVIP

看看人家那后端API接口写得,那叫一个优雅!.docx

  1. 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  4. 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  5. 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  6. 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  7. 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
看看人家那后端API接口写得,那叫一个优雅! 记录一次线上JVM堆外内存泄漏问题的排查过程与思路,其中夹带一些JVM内存安排机制以及*常用的JVM问题排查指令和工具共享*,期望对大家有所挂念。 ? 在整个排查过程中,我也走了不少弯路,但是在文章中我仍旧会把完整的思路和想法写出来,当做一次阅历教训,给后人参考,文章最终也总结了下内存泄漏问题快速排查的几个准绳。 ? 本文的次要内容: 毛病描述和排查过程 毛病缘由和处理方案分析 JVM堆内内存和堆外内存安排原理 常用的进程内存泄漏排查指令和工具引见和使用 毛病描述 ? 8月12日半夜午休时间,我们商业服务收到告警,服务进程占用容器的物理内存(16G)超过了80%的阈值,并且还在不断上升。 ? ? 监控系统调出图表查看: ? ? 像是Java进程发生了内存泄漏,而我们堆内存的限制是4G,这种大于4G快要吃满内存应当是JVM堆外内存泄漏。 ? 确认了下当时服务进程的启动配置: -Xms4g -Xmx4g -Xmn2g -Xss1024K -XX:PermSize=256m -XX:MaxPermSize=512m -XX:ParallelGCThreads=20 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+UseCMSCompactAtFullCollection -XX:CMSInitiatingOccupancyFraction=80 ? 虽然当天没有上线新代码,但是当天上午我们正在使用消息队列推送历史数据的修复脚本,该任务会大量调用我们服务其中的某一个接口,所以初步怀疑和该接口有关。 ? 下图是该调用接口当天的访问量变化: ? ? 可以看到案发当时调用量相比正常情况(每分钟200+次)提高了很多(每分钟5000+次)。 ? 我们临时让脚本停止发送消息,该接口调用量下降到每分钟200+次,容器内存不再以极高斜率上升,一切好像恢复了正常。 ? 接下来排查这个接口是不是发生了内存泄漏。 排查过程 ? 首先我们先回顾下Java进程的内存安排,便利我们下面排查思路的阐述。 ? 以我们线上使用的JDK1.8版本为例。JVM内存安排网上有很多总结,我就不再进行二次创作。 ? JVM内存区域的划分为两块:堆区和非堆区。 ? 堆区:就是我们熟知的重生代老年月。 非堆区:非堆区如图中所示,有元数据区和直接内存。 ? ? 这里需要额外留意的是:永久代(JDK8的原生去)存放JVM运转时使用的类,永久代的对象在full GC时进行垃圾收集。 ? 复习完了JVM的内存安排,让我们回到毛病上来。 · 堆内存分析 ? 虽说一开头就基本确认与堆内存无关,由于泄露的内存占用超过了堆内存限制4G,但是我们为了保险起见先看下堆内存有什么线索。 ? 我们观看了重生代和老年月内存占用曲线以及回收次数统计,和平常一样没有大问题,我们接着在事故现场的容器上dump了一份JVM堆内存的日志。 · 堆内存Dump ? 堆内存快照dump命令: jmap -dump:live,format=b,file=xxxx.hprof pid ? 画外音:你也可以使用jmap -histo:live pid直接查看堆内存存活的对象。 ? 导出后,将Dump文件下载回本地,然后可以使用Eclipse的MAT(Memory Analyzer)或者JDK自带的JVisualVM打开日志文件。 ? 使用MAT打开文件如图所示: ? ? 可以看到堆内存中,有一些nio有关的大对象,比如正在接收消息队列消息的nioChannel,还有nio.HeapByteBuffer,但是数量不多,不能作为推断的依据,先放着观看下。 ? 下一步,我开头扫瞄该接口代码,接口内部次要规律是调用集团的WCS客户端,将数据库表中数据查表后写入WCS,没有其他额外规律 ? 发觉没有什么特殊规律后,我开头怀疑WCS客户端封装能否存在内存泄漏,这样怀疑的理由是,WCS客户端底层是由SCF客户端封装的,作为RPC框架,其底层通讯传输协议有可能会申请直接内存。 ? 是不是我的代码动身了WCS客户端的Bug,导致不断地申请直接内存的调用,最终吃满内存。 ? 我联系上了WCS的值班人,将我们遇到的问题和他们描述了一下,他们回复我们,会在他们本地执行下写入操作的压测,看看能不能复现我们的问题。 ? 既然等待他们的反馈还需要时间,我们就预备先本人揣摩下缘由。 ? 我将怀疑的目光停留在了直接内存上,怀疑是由于接口调用量过大,客户端对nio使用不当,导致使用ByteBuffer申请过多的直接内存。 ? 画外音:最终的结果证明,这一个先入为主的思路导致排查过程走了弯路。在问题的排查过程中,用合理的猜想来缩小排查范围是可以的,但最好先把每种可能性都列清

文档评论(0)

duanbingbing + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档