当前位置: 首页 > news >正文

广州网站建站jsp网站首页那栏怎么做

广州网站建站,jsp网站首页那栏怎么做,开网站建设公司赚钱吗,免费建站网站制作模板优质博文:IT-BLOG-CN 一、问题描述 淘宝后台应用从今年某个时间开始docker oom的量突然变多,确定为堆外内存泄露。 后面继续按照上一篇对外内存分析方法的进行排查(jemalloc、pmap、mallocpmap/mapsNMTjstackgdb),但都没有定位到问题。至于…

优质博文:IT-BLOG-CN

一、问题描述

淘宝后台应用从今年某个时间开始docker oom的量突然变多,确定为堆外内存泄露。

后面继续按照上一篇对外内存分析方法的进行排查(jemallocpmapmalloc+pmap/maps+NMT+jstack+gdb),但都没有定位到问题。至于为什么没有定位到问题,后面会根据问题的特点进行分析。

至此,回到原点。其实也不是原点,最起码已经确定了是堆外内存off-heap,而不是Native Memory(JVM自身所用内存)泄露。所以你看,很多时候问题排查其实是排除法(苦涩的笑)。

二、排查过程

堆外内存off-heap的泄露,不外乎有以下几个原因:
【1】流没有关闭;
【2】Unsafe.allocateMemory内存没释放;
【3】jni内存没有释放;

其中流没有关闭是最常见的,而23出现的概率是比较低的,所以先排查流没有关闭的可能。

2.1 走寻常路

对于流没有关闭导致泄露的定位,一般来说有以下4种方式:
【1】看代码;
【2】用jemalloc分析;
【3】分析堆内存找小尾巴;

2.1.1 看代码

流未关闭的话,一般来说都是因为没有显式地调用close()方法或没有使用try-with-resource的方式管理流。比如下面这段代码就存在流未关闭的情形:
在这里插入图片描述

像下面的这段代码,流会被try-with-resource机制去关闭,正常情况下不会出现内存泄露。而存在泄露的应用,恰恰就是用try-with-resource机制去管理流,所以排除这里的嫌疑。
在这里插入图片描述

2.1.2 用jemalloc分析

这里用到jemalloc主要是利用它的heap dump以及它的jeprof命令来分析java进程的内存分配情况。注意这里的heap不是jvm堆内存,而是操作系统视角的内存布局,比如heapstackBSS、数据段、代码段,这里不是本文的重点,就不展开描述了……

使用jemalloc分析内存分配的过程很多文章都有描述,这里也不展开了,结果是通过jeprof生成的pdf文件,依然没有发现导致流未关闭的场景,只能作罢。

2.1.3 分析堆内存

通过看代码的方式以及jemalloc都没法定位到流未关闭的情形,考虑代码走查难免有遗漏,同时应用使用了大量的第三方组件,第三方组件会不会存在流未关闭的可能呢?但很显然,如果去分析第三方组件的代码会累吐血。联想到流没有关闭的情形,一般会在堆内存里面留一些引用的痕迹,于是开始dump java堆内存。

内存dump下来后,通过MAT查找java.lang.ref.FinalizerInputStreamOutputStream相关的对象,依然一无所获,这时开始怀疑内存的泄露跟流未关闭没有关系。

2.1.4 内部工具分析

公司内部提供了一个跟踪内存分配的工具,通过扩展malloc方法获取到分配内存的调用线程和内存地址,通过jstack打印线程栈,结合gdbpmap等方式获取可疑内存段,以定位内存泄露源头。通过这种方式依然没有找到任何线索,同时jstack的方式会导致应用出现短暂的停顿safepoint而影响性能,所以这种方式也放弃了。

2.2 走了弯路

在暂时排除了流未关闭的嫌疑后,这时转向分析直接用Unsafe.allocateMemory分配的内存。有些组件不会基于java.nio.DirectByteBuffer(int cap)申请堆外内存,而是直接用unsafe.allocateMemory方法申请内存,这时候MaxDirectMemorySize是限制不住堆外内存的用量的,当然基于DirectByteBuffer申请的堆外内存,最终也是基于unsafe.allocateMemory方法申请内存,所以这里只要分析unsafe.allocateMemory申请的内存即可。到这里,前面提到的神器async-profiler就粉墨登场了。

async-profiler的安装步骤这里就不介绍了,可以自行安装。安装完毕使用以下脚本就可以分析Unsafe_AllocateMemory0的内存分配情况了。

sudo -u deploy /tmp/async-profiler-2.9-linux-x64/profiler.sh -e Unsafe_AllocateMemory0 -d 1200 -f /tmp/unsafe_alloc-$(pgrep java)-$(date +'%y%m%d%H%M').html $(pgrep java) 

这里-e代表要分析的事件,-d代表分析的时长,以秒为单位。生成的结果是一张火焰图,你可以下载下来在浏览器上查看哪块用到了Unsafe_AllocateMemory0来分配内存。

比较悲催的是,通过Unsafe_AllocateMemory0分配的内存比较少,所以这里的嫌疑也被排除了。所以分析Unsafe_AllocateMemory0这一步算是走了弯路。

2.3 柳暗花明

前面所有的手段都用尽之后,已经快一个星期过去了。在前面的手段都用尽之后,尝试分析jni的内存分配情况。其实这时候有点死马当作活马医的味道了。

jni(Java Native Interface),简单说就是Java调用c/c++写的程序,实现更强的功能。c写的程序,要分配内存,一般是通过malloc()方法向操作系统申请内存。在malloc的实现中,一般分配大块内存 128KB会使用mmap分配内存空间。而async-profiler可以通过分析linux perf_event中的perf_event_mmap_page来追踪内存分配情况的。想到这里,便尝试通过下面的命令来追踪系统层面malloc情况:

sudo -u deploy /tmp/async-profiler-2.9-linux-x64/profiler.sh --loop 1h -e malloc -f /tmp/malloc-$(pgrep java)-%t.html $(pgrep java) 

这个命令中的–loop参数是能够以1个小时间隔不间断跟踪内存分配情况,如果你想长时间进行问题定位,可以尝试使用一下这个参数,profiler会每隔1个小时生成一个html文件,是不是很方便?

-e malloc就是告诉async-profiler去追踪perf_event_mmap_page的内存分配。

运行了1个小时后,就得到了下面的这个内存分配火焰图:
在这里插入图片描述

从图中可以看出,zstd-jni这个组件分配了大量的内存。因为在之前我们通过review代码排查流没有关闭的场景时,是看过这段代码的,但当时没有发现什么问题。但从火焰图中看到分配的内存量,总感觉不对劲。这时候忽然想到,能不能从日志中找到什么蛛丝马迹呢?于是开始扒日志,这时,一个broken pipe的异常引起了我的注意:
在这里插入图片描述

这种broken pipe的异常其实蛮常见的,尤其在有一方断开连接时,很容易就出现这种异常。但顺着调用栈往下看,顿时眼前一亮,其中有ZstdOutputStream的调用。流里面的异常那是很容易泄露的,于是进入到ZstdOutputStream.java 178行看代码,发现了zstd-jni 1.3.x版本存在的bug:当ZstdOutputStream关闭流的时候,会尝试把剩余的数据发送出去。但这时候如果连接已经关闭了,它就咯咯了,导致流关闭不掉,jni的内存也释放不掉。
在这里插入图片描述

这个bug,在1.4.4-11版本中就修复了,我们可以看到作者用try-finally捕获了out.write的异常,这样不管zstd依赖的流的状态如何,它最终都会释放自己使用的资源。
在这里插入图片描述

定位到问题之后就好办多了,将zstd-jni的版本升级到1.4.9-5之后的版本,这个问题就不存在了,下面是修复后RSS的情况,可以看到RSS很平稳了:
在这里插入图片描述

三、总结

这个case从开始排查到最终定位到问题,花费了一个星期的时间,成本巨大,回过头看看排查的步骤,貌似也没什么问题,但终究是走了一些弯路:

3.1 忽略了异常信息

如果最开始就重视异常信息的话,那么这个问题可能很早就定位到了。但这个应用自己不是直接责任人,而且在看到broken pipe的时候犯了经验性错误,没有往影响流关闭的角度想,导致方向错误,浪费了大量的时间。

所以,系统中任何的异常,都要重视起来,避免产生更严重的问题。

3.2 jemalloc失效

jemalloc在分析内存持续泄露方面比较方便,但对于非稳定复现的场景,如果采样间隔过久,有可能会导致错过问题点。而如果你将采样间隔调短,又会造成生成大量的dump文件,在用jeprof生成分析报告的时候,可能会导致too many arguments的错误而无法生成分析报告。

3.3 内部工具失效

内部工具,能够把可疑的内存段内容用strings命令查看,某些场景是能够发现蛛丝马迹的,为什么这个case就不行了呢?这里猜测是因为zstd对数据做了压缩,用strings看到的全是乱码,没法发现数据的特征;

综上,问题排查很多时候真的像排雷一样,一个个的去排除。这需要的是耐心和毅力,当你最终定位到问题的时候,那种如释重负的感觉会让自己觉得一切都是值得的。

http://www.yayakq.cn/news/516435/

相关文章:

  • 安徽工程建设造价信息网站安徽网站定制
  • 免费素材网站psd小程序做网站登录
  • 网站文字优化方案建设厅八大员
  • 爱民网站制作wordpress登陆入口修改
  • 九江网站制作四川在线
  • 学做网站设计小程序如何赚钱
  • 网站怎么做引流网站托管公司
  • 滑县网站建设哪家专业江苏建设网站
  • 新建门户网站的建设自查湖北建设
  • 资料网站怎么做的备案做电影网站
  • 诚信建设网站的作用品牌营销策划方案ppt
  • 正规网站建设推荐谁好呢网站群建设方案6
  • 程序员帮忙做放贷网站网页设计代码大全表单
  • 做捕鱼网站巴青网站制作
  • 直播网站怎么建设泉州公司网页制作
  • 网站首页模板设计图福建省建设安全监督站的网站
  • 温州瑞安网站建设平台临沂网站建设推广
  • 淘客网站开发源代码适合两个人运动前看的电影
  • 网站建设贰金手指下拉壹玖wordpress不能自定义
  • 网站推广方式组合网页与网站的关系
  • 网站排名提高集团品牌官网建设
  • 四川住房城乡建设厅网站电话汕头网站设计有限公司
  • awds网站开发留学遵义本地网络平台
  • 南昌网站建设报价dw做的网站不显示
  • 注册网站wordpress 分类不显示全文
  • 网站被禁止访问怎么打开做预算的网站
  • 校园网站国外做科研的网站
  • 生成静态页面网站源码网站开发设计的完成情况
  • iis部署网站项目济宁做网站的
  • 那家公司做网站比较好南阳网站建设口碑