精华内容
下载资源
问答
  • 起因:最近新上线的服务内存(部署在linux平台)每天一天都会上涨一点点,现象如下图所示。想到每天要通过一个SO库与一个数据源进行TCP的连接与断开,于是便展开排查工作。现象.jpg因为不是紧急的线上问题,于是在开发...

    起因:

    最近新上线的服务内存(部署在linux平台)每天一天都会上涨一点点,现象如下图所示。想到每天要通过一个SO库与一个数据源进行TCP的连接与断开,于是便展开排查工作。

    a52f1a72d94c

    现象.jpg

    因为不是紧急的线上问题,于是在开发站搭建环境进行问题重现。主站上面程序是每天9点进行连接操作,下午四点进行TCP长连接的断开操作,开发站为了放大这个问题,写了一个循环进行重复连接与断开,观察内存变化情况。

    排查步骤:

    step1:确认是否内存是在java虚拟机内部产生泄漏。

    程序启动时加如下参数ativeMemoryTracking观察内存(注意要在-jar前面,不然不会起作用)

    /usr/local/jdk1.8.0_251/bin/java -XX:NativeMemoryTracking=detail -jar

    使用如下命令观察虚拟机内部内存情况

    jcmd VM.native_memory

    发现java虚拟机申请的内存远小于该进程实际占用的内存,所以可以确定是由于C++申请内存没有释放导致的泄漏问题。

    a52f1a72d94c

    实际占用内存

    a52f1a72d94c

    Java虚拟机占用内存

    step2:操作系统层面确定是哪块内存泄漏

    使用pmap命令比较查看该进程哪一块内存只上涨不回收,发现上涨的内存都是堆内存,下面的工作就是进一步分析堆内存是哪些线程进行申请并且没有进行释放。

    pmap -x | sort -k 3 -n -r

    a52f1a72d94c

    程序开始运行进程内存分配

    a52f1a72d94c

    程序运行一段时间后内存分配

    step3:使用gperftools进行代码泄漏分析,该工具的介绍、安装和使用可以参考文章最后的参考文献。

    首先在启动脚本添加相关分析SO库的配置

    export LD_PRELOAD=/usr/local/lib/libtcmalloc.so

    export HEAPPROFILE=/perftools #分析文件输出位置

    然后重启程序并启动疑似内存泄漏程序,使用命pprof令分析输出结果。

    发现主要内存泄漏是由于HandleSnapshotData和handleCodeTableData方法导致的,至此排查结束,联系该so库的开发团队进行问题反馈。

    pprof --text libtapi_jni.so /perftools/.0014.heap | head -10

    pprof --text libtapi_jni.so /perftools/.0057.heap | head -10

    a52f1a72d94c

    分析结果

    总结:

    虽然这个内存泄漏问题每天只会涨几十M,但是这始终是一个隐藏的雷点,说不定哪天在线上就爆雷了,这需要开发人员像呵护孩子一样呵护自己的服务,观察他的喜怒哀乐,时长给予他关怀。

    在排查问题的过程当中遇到了很多坑,比如jvm参数添加后程序启动就崩溃,后来查到是由于该jdk版本的一个bug,升级到1.8.0_251就能解决;又比如使用gperftools这个工具时,因为输出的文件太多,没有细致的去观察输出的文件规律,导致浪费了几个小时去查问题等等,需要在以后的工作中更加细致认真。

    参考文献:

    展开全文
  • C++之内存泄漏排查

    千次阅读 2021-10-08 17:52:42
    C++语言由于其灵活的指针特性,即带来了便捷性也带来了潜在的问题,由于在编程的不规范性以及相关问题,C++程序员面临的一大问题就是内存泄漏问题,博主就因为在上个项目的开发中,因为图像方面的内存泄露苦不堪言,...
     
    

    一 经验排查

    • 有经验的程序员会对程序中申请内存的地方进行排查,例如malloc或者new关键字的地方进行跟踪,一种情况是我们按照程序逻辑进行了申请和释放,要提防程序在发生异常时没有如我们所期望的那样进行内存释放,此时也应当防止内存泄漏。

    二 使用Visual Leak Detector for Visual C++

    2.1 Visual Leak Detector for Visual C++简介

    • Visual C++ 提供了内置的内存泄漏检测,但它的功能充其量只是最小的。此内存泄漏检测器是作为 Visual C++ 提供的内置内存泄漏检测器的免费替代品而创建的。以下是 Visual Leak Detector 的一些功能,内置检测器中不存在这些功能:

    • 为每个泄漏块提供完整的堆栈跟踪,包括可用的源文件和行号信息。
      检测大多数(如果不是全部)进程内内存泄漏类型,包括基于 COM 的泄漏和基于纯 Win32 堆的泄漏。

    • 选定的模块(DLL 甚至主 EXE)可以从泄漏检测中排除。
      提供泄漏块的完整数据转储(以十六进制和 ASCII 格式)。
      可定制的内存泄漏报告:可以保存到文件或发送到调试器,并且可以包含可变级别的详细信息。
      其他用于 Visual C++ 的售后泄漏检测器已经可用。但大多数真正流行的,如 Purify 和 BoundsChecker,都非常昂贵。存在一些免费的替代方案,但它们通常太具有侵入性、限制性或不可靠。 Visual Leak Detector 是目前唯一可免费使用的 Visual C++ 内存泄漏检测器,它将上述所有专业级功能整齐地打包在一个易于使用的库中。

    2.2 Visual Leak Detector源码获取编译

    2.2.1 源码获取,相关git地址

       git clone  https://github.com/oneiric/vld
    

    2.2.2 发布版本获取

    • 在git主页有Visual Leak Detector for Visual C++ Releases,只需要下载对应的版本,进行安装即可。

    2.2.3 进行编译

    • 本代码要求的vs版本为2019,博主使用的版本为为2015,在编译时候会报错
     项目-->属性--->常规-->平台工具集--->选择 Visual Studio 2015(v140)确定,就OK
    

    2.2.4 自带gtest工程测试

    • 编译项目自带的vld_main进行测试,项目中自带gtest工程对相关内存泄漏场景进行了自测

    2.3 如何测试自己的项目呢

    2.3.1 配置工程

    • 在自己的工程中引入vld.h文件,并在链接库中配置vld.lib库
      引入头文件
      配置库路径
      配置链接库

    • 设置当前工程为Debug模式,才能显示堆栈相关的调用信息
      配置debug模式

    2.3.2 编写简单的测试用例

    • three.h

        #pragma once
        class three
        {
        public:
            three();
            ~three();
        };
      
      
    • three.cpp

       #include "three.h"
      
       three::three()
       {
       }
      
       three::~three()
       {
       }
      
      
    • main.cpp

        #include<stdlib.h>
        #include<stdio.h>
        #include <iostream>
        #include <vld.h>
        #include "three.h"
        using namespace std;
      
        int main()
        {
            cout << "vld test begin" << endl;
            int *one = new int[30];
            char *two = new char[40];
            three * tmp = new three();
            return 0;
        }
      

      2.3.3 检测结果如图

    检测结果- 程序执行完之后会在终端显示内存泄漏的的个数,并同时会打印相关的内存泄漏的堆栈信息,当鼠标点击终端信息输出的位置时,同时会在上方代码指示哪一行出现内存泄漏。

    三 使用总结

    • 总的来说,该工具的使用还是非常便捷的,相比较于自己去按个去排查,会省很多精力,尤其是面对代码量特别大的工程的时候,排查内存泄漏是一件特别让人糟心的事情,当然缺点也是有的,比如跨工程的内存泄漏是不太容易检测出来,偶尔还会误报一些信息,但是相比于收费的检测软件,这个检测软件已经很良心了,希望本次分享对大家有所帮助,如果感兴趣的话,可以点赞加关注,谢谢!
    展开全文
  • 线上内存泄露排查

    2021-03-25 21:09:17
    背景: 上周网关上线后,隔了几小时突然服务不可用,重启后恢复,隔几小时后依然如此;由于此次网关改动的代码较多,一时不好定位。...从系统监控图可以看出,自从服务上线后已用内存就一直在申请、上升,没有释放,那

    背景:

    上周网关上线后,隔了几小时突然服务不可用,重启后恢复,隔几小时后依然如此;由于此次网关改动的代码较多,一时不好定位。

    问题回放:

    在这里插入图片描述
    从系统监控图上看,内存一直在增长,最终到爆;

    抓取到服务器宕机时刻的日志如下:
    在这里插入图片描述
    o.netty.util.internal.OutOfDirectMemoryError: failed to allocate

    看到以上的日志,大体可以知道是直接内存分配不足导致,与系统监控图上看比较吻合;

    从系统监控图可以看出,自从服务上线后已用内存就一直在申请、上升,没有释放,那么接下来就是定位为什么会出现内存不释放的问题了!因为我们应用的网关项目是使用的Spring Cloud Gateway进行搭建的,而Spring Cloud Gateway又是使用的Netty框架进行搭建的,这正好和以上报错io.netty.util.internal.OutOfDirectMemoryError日志恰巧对应上,下面就查阅了好多资料,说Gateway低版本确实存在过该问题,升级版本即可解决此类问题,于是将现有的Spring Cloud版本在Finchley基础上升到了Hoxton,并在仿真环境进行了压测(并发1000),压了半个小时,并没有出现宕机异常,于是当天晚上就将代码进行上线,但是上线之后查看ELK日志,发现还是存在很多的错误日志如下:
    在这里插入图片描述

    LEAK: ByteBuf.release() was not called before it's garbage-collected

    竟然是内存泄漏最终导致的内存溢出,按理说像Spring Cloud Gateway这么成熟的框架不应该会出现类似的问题,于是排查我们的项目代码,发现竟然是我们自己网关项目的一个全局过滤XSS攻击的filter,里面有使用Netty的一个databuffer,但是这个databuffer没有进行释放导致,于是将该databuffer进行手工释放DataBufferUtils.release(dataBuffer);修改完该瑕疵之后,线上内存监控趋于平稳。

    展开全文
  • 本文涉及以下内容开启NMT查看JVM内存使用情况通过pmap命令查看进程物理内存使用情况smaps查看进程内存地址gdb命令dump内存块背景最近收到运维反馈,说有项目的一个节点的RSS已经是Xmx的两倍多了,因为是ECS机器所以...

    dd7ad3838105

    本文涉及以下内容

    开启NMT查看JVM内存使用情况

    通过pmap命令查看进程物理内存使用情况

    smaps查看进程内存地址

    gdb命令dump内存块

    背景

    最近收到运维反馈,说有项目的一个节点的RSS已经是Xmx的两倍多了,因为是ECS机器所以项目可以一直运行,幸亏机器内存充足,不然就可能影响到其他应用了。

    排查问题

    通过跳板机登录到目标机器,执行top命令,再按c,看到对应的进程所占用的RES有8个多G(这里当时忘记截图了),但是实际上我们配置的Xmx只有3G,而且程序还是正常运行的,所以不会是堆占用了这么多,于是就把问题方向指向了非堆的内存。

    首先想到通过Arthas查看内存分布情况,执行dashboard命令,查看内存分布情况

    dd7ad3838105

    发现堆和非堆的内存加起来也就2个G不到,但是这里看到的非堆只包含了code_cache和metaspace的部分,那有没有可能是其他非堆的部分有问题呢?

    NMT

    NMT是Native Memory Tracking的缩写,是Java7U40引入的HotSpot新特性,开启后可以通过jcmd命令来对JVM内存使用情况进行跟踪。注意,根据Java官方文档,开启NMT会有5%-10%的性能损耗。

    -XX:NativeMemoryTracking=[off | summary | detail]

    # off: 默认关闭

    # summary: 只统计各个分类的内存使用情况.

    # detail: Collect memory usage by individual call sites.

    添加-XX:NativeMemoryTracking=detail命令到启动参数中,然后重启项目。

    跑了一段时间后top看了下进程的RES,发现已经5个多G了

    执行jcmd VM.native_memory summary scale=MB

    dd7ad3838105

    从图中可以看到堆和非堆的总使用内存(committed)也就2G多,那还有3个G的内存去哪里了呢。

    pmap

    pmap命令是Linux上用来开进程地址空间的

    执行pmap -x | sort -n -k3 > pmap-sorted.txt命令可以根据实际内存排序

    查看pmap-sorted.txt文件,发现有大量的64M内存块

    dd7ad3838105

    难道是linux glibc 中经典的 64M 内存问题?之前看挖坑的张师傅写过一篇文章(一次 Java 进程 OOM 的排查分析(glibc 篇))讲过这个问题,于是准备参考一下排查思路

    尝试设置环境变量MALLOC_ARENA_MAX=1,重启项目,跑了一段时间以后,再次执行pmap命令查看内存情况,发现并没有什么变化,看来并不是这个原因,文章后面的步骤就没有什么参考意义了。

    smaps + gdb

    既然可以看到有这么多异常的内存块,那有没有办法知道里面存的是什么内容呢,答案是肯定的。经过一番资料查阅,发现可以通过gdb的命令把指定地址范围的内存块dump出来。

    要执行gdb的dump需要先知道一个地址范围,通过smaps可以输出进程使用的内存块详细信息,包括地址范围和来源

    cat /proc//smaps > smaps.txt

    查看smaps.txt,找到有问题的内存块地址,比如下图中的 7fb9b0000000-7fb9b3ffe000

    dd7ad3838105

    启动gdb

    gdb attach

    dump指定内存地址到指定的目录下,参数的地址需要在smaps拿到地址前加上0x

    dump memory /tmp/0x7fb9b0000000-0x7fb9b3ffe000.dump 0x7fb9b0000000 0x7fb9b3ffe000

    显示长度超过10字符的字符串

    strings -10 /tmp/0x7fb9b0000000-0x7fb9b3ffe000.dump

    dd7ad3838105

    发现里面有大量的图中红框中的内容,这个内容是后端给前端websocket推送的内容,怎么会驻留在堆外内存里面呢?检查了项目代码发现,后端的websocket是使用的netty-socketio实现的,maven依赖为

    com.corundumstudio.socketio

    netty-socketio

    1.7.12

    看了下最近的版本发布日志,发现这个框架的最新版本已经是1.7.18,而且中间发布的几个版本多次修复了内存泄漏相关的问题

    dd7ad3838105

    于是把依赖版本升级到最新版,重新发布后,第二天在看,发现RES还是变得很高

    中间又仔细看了使用框架的相关代码,发现断开连接的时候没有调用leaveRoom方法,而是调用了joinRoom,导致群发信息的时候还会往断开的连接里面发送数据(理论上会报错,但是没有看到过相关日志),修复代码后又重新发布了一版,跑了一天在看,依然没有效果。

    结论

    到这一步可以确认的是内存泄漏的问题肯定跟这个websocket及相关功能有关的(因为中间升级到1.7.18发现websocket连不上了,后来降到了1.7.17,期间有较长的时间是没有暴露websocket服务的,而正好这段时间的RES是非常稳定的,完全没有上涨的趋势,因为这个功能点比较小,用户没有什么感知),最后,经过跟产品方面沟通,决定把这里的websocet去掉,改为前端直接请求接口获取数据,因为这里的功能就是为了实时推送一个未读信息数量,而这个信息其实很少有用户关心,所以,就改成刷新页面的时候查询一下就行了,就这样,问题算是变相解决了😁。至于这个问题的具体原因还是没有找到,可能是框架BUG,也可能是代码使用问题,后面需要重度依赖websocket的时候或许会基于netty自己写一套,这样比较可控一点。

    总结

    虽然经过这么多的努力,最终只是证明了【没有需求就没有BUG】这句话,但是中间还是有挺多的收获的,很多命令也是第一次使用,中间还有一些曲折,就没有一一写出来了,挑选了一些比较有价值的过程写了这篇文章总结,希望可以分享给有需要的人,以后遇到类似问题,可以做个经验参考。

    dd7ad3838105

    展开全文
  • java内存泄露排查总结

    2021-01-18 11:14:24
    1.内存溢出和内存泄露 一种通俗的说法: 内存溢出:你申请了10个字节的空间,但是你在这个空间写入了11个或者以上字节的数据,则出现溢出 内存泄露:你用new申请了一块内存,后来很长时间都不使用了,但是因为...
  • 记一次内存泄漏排查过程 jmap -histo
  • Java内存泄露如何排查

    2021-02-13 00:04:07
    Java内存泄露是常常出现的问题,Java攀登网进行了该问题的整理...在 Java中,内存泄漏就是存在一些被分配的对象,这些对象有下面两个特点:1)首先,这些 对象是可达的,即在有向图中,存在通路可以与其相连;2)其次...
  • 作为c的程序员,最常见的就是排查内存泄漏,不过我们一般的内存泄漏是针对特定的程序去排查,相对来说比较容易,但是如果是维护人员,不知道哪个程序有内存泄漏,甚至是应用程序的内存泄漏,还是内核的...
  • 截断代码来不断缩减范围,配合使用来定位内存泄漏具体代码。 1 2 3 4 5 6 7 8function print_max_memory(){ static $max_memory = 0; $memory = memory_get_usage(); if($max_memory $memory){ $max_memory = $...
  • 内存泄漏是指无用对象(不再使用的对象)持续占有内存或无用对象的内存得不到及时释放,从而造成内存空间的浪费称为内存泄漏。内存泄露有时不严重且不易察觉,这样开发者就不知道存在内存泄露,需要自主观察,比较严重...
  • 内存泄漏通常表示:一个应用程序的某些对象在完成它的的生命周期后,由于它被其他对象意外引用,导致后续gc无法对它进行回收,长此以往就会导致程序性能的下降以及潜在的 OutOfMemoryEx...
  • python内存泄露排查

    2021-03-05 22:09:48
    最近线上某台虚拟机隔三差五就会挂掉,通过业务日志基本上排查到每次出错都源于某一个请求。于是对该请求展开排查。1,先确认罪魁祸首:执行该...而VIRT,RES,内存占比却有显著提升,且执行完成后并未下降。多次...
  • C++内存泄漏排查

    2021-01-13 20:43:31
    linux c++内存泄漏排查方案汇总 参考:https://www.cnblogs.com/kex1n/p/11572313.html 使用mtrace分析内存泄漏 参考:https://zhuanlan.zhihu.com/p/83547768
  • C++ 实现内存泄露检查

    2021-11-07 23:56:29
    内存泄漏一直是 C++ 中比较令人头大的问题, 即便是很有经验的 C++程序员有时候也难免因为疏忽而写出导致内存泄漏的代码。...所以本项目中的内存泄漏检查器将实现一个用于短期内存泄露检查器。 ...
  • 排查页面的内存泄漏

    2021-04-27 15:59:14
    前言 总所周知,js是有垃圾回收机制的,大致分为标记清除和引用计数,目前主流浏览器都用的是标记清除...内存泄漏就是指由于疏忽或程序的某些错误造成未能释放的已经不再使用的内存的情况。简单来说就是一个变量已经不
  • 此时可选择注释相关代码,再次进入这个界面退出,再次查看这个界面的泄露位置,可逐一排查该界面的内存泄露。 选择堆栈后点击保存可保存为hprof文件,方便下次查看。 点击加号可选择导入保存的hprof文件 接下来自己...
  • 内存泄露内存指的是虚拟内存。如果发生内存泄露,最终导致的结果是机器程序运行越来越慢,存储空间越来越不足,一直到整个系统都崩溃。我们平常在使用电脑的时候,很难感觉到内存泄露的存在。其实一次性内存泄露...
  • Python 内存泄漏问题排查

    千次阅读 2021-02-13 21:51:58
    以之前Java OOM的排查经验,解决这种问题一般需要dump内存快照,分析内存分配,对象引用链和GC状态等等。因此我猜测Python的OOM排查应该也是类似的。 二. 摸索分析 1. 了解内存分析 工欲善其事,必先利其器。我先对...
  • 1.查看各个进程的ION:/sys/kernel/debug/ion/heaps # cat system-heapcat system-heapclient pid size----------------------------------------------------surfaceflinger 211 ...
  • 一个系统后台服务进程,可能包括多个线程,在生成...0.判读系统程序是否存在内存泄露对于频繁快速申请内存的应用,可以允许下面的命令:top-p `pidof YourProgrogram`如果看到系统内存使用率一直上身,没有下降,就...
  • 内存泄漏监控和排查

    2021-08-08 16:09:56
    内存泄漏现象 1、tps出现大幅波动,并慢慢降低,甚至降为0,响应时间随之波动,慢慢升高; 压测开始不久: 压测一段时间之后: 2、通过jstat命令看到,Jvm中Old区不断增加,FullGC非常频繁(几乎一秒进行一...
  • 点击关注公众号,Java干货及时送达来源 |https://zhenbianshu.github.io/前些日子小组内安排值班,轮流看顾我们的服务,主要做一些报警邮件处理、Bug 排查、...
  • 采用了Unity memory profile工具,两次内存对照,发现有严重的内存泄露情况产生。有关Unity memory profile工具的安装和使用, 大家可以去度娘search,这个几乎一抓一大把 跑了30分钟样子,在RenderTexture和...
  • 【赛迪网报道】Linux系统下真正有危害的是内存泄漏的堆积,这会最终消耗尽系统任何的内存。下面是排查和解决方案与大家一起分享。1、Linux 内存监控内存泄漏的定义:一般我们常说的内存泄漏是指堆内存的泄漏。堆内存...
  • 栈溢出,堆溢出,永久代溢出,内存泄漏排查JAVA虚拟机1.虚拟机栈和本地方法栈溢出:1.如果线程请求的栈深度大于虚拟机所允许的最大深度,抛出StackOverflowError异常。单线程下,递归太深或方法调用层级过多,使栈帧...
  • 业务中内存泄漏的现象以及排查思路 内存泄漏的现象 我们将服务发布到测试环境中之后,可以从内存监控的看板中看到,内存使用量随着时间的推移会一直增加,而且会一直达到内存设置的限制并且重启Po
  • 线上我们经常遇到 cpu 100%或者内存泄漏问题,面对这些常见的问题我们如何排查,快速定位问题? 1. cpu 100% 问题排查 1.首先找到cpu占用率较高的java进程号 主要使用命令: top -c 显示运行中进程列表信息,并且...
  • Qt内存泄漏总结(包括检测工具)

    千次阅读 2021-01-09 08:37:55
    Qt内存管理机制:Qt 在内部能够维护对象的层次结构。对于可视元素,这种层次结构就是子组件与父组件的关系;对于非可视元素,则是一个对象与另一个对象的从属关系。在 Qt 中,在 Qt 中,删除父对象会将其子对象一起...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 135,989
精华内容 54,395
关键字:

内存泄漏怎么排查