精华内容
下载资源
问答
  • 1、执行 free -h 查看内存使用情况 (base) [root@HK-AI sinoma]# free -h total used free shared buff/cache available Mem: 31G 24G 766M 121M 6.2G 6.3G Swap: 15G 0B 15G (base) [root@HK-AI sinoma]# 2、...

    1、执行 free -h 查看内存使用情况

    (base) [root@HK-AI sinoma]# free -h
    
    total used free shared buff/cache available
    Mem: 31G 24G 766M 121M 6.2G 6.3G
    Swap: 15G 0B 15G
    (base) [root@HK-AI sinoma]# 
    

    2、内存不足,查看使用top5 内存的进程,命令 :top -d 5

    (base) [root@HK-AI sinoma]# top -d 5
    

    top - 14:01:01 up 133 days, 23:36, 2 users, load average: 0.28, 0.31, 0.31
    Tasks: 271 total, 1 running, 269 sleeping, 1 stopped, 0 zombie
    %Cpu(s): 5.7 us, 1.1 sy, 0.0 ni, 93.2 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
    KiB Mem : 32765644 total, 781904 free, 25436940 used, 6546800 buff/cache
    KiB Swap: 16515068 total, 16515068 free, 0 used. 6628184 avail Mem

    PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 
    62303 root 20 0 1451716 129672 34580 S 26.9 0.4 5181:00 python 
    50264 root 20 0 25.140g 0.021t 72676 S 2.6 68.4 885:09.28 gunicorn 
    39928 root 20 0 3357936 260700 71920 S 2.2 0.8 422:02.91 gunicorn 
    55800 root 20 0 1218432 211736 64816 S 2.2 0.6 126:58.33 gunicorn 
    39929 root 20 0 3357884 260596 71892 S 2.0 0.8 422:25.18 gunicorn 
    39930 root 20 0 3357884 260600 71892 S 1.8 0.8 422:04.32 gunicorn 
    44877 root 20 0 1259376 105180 24668 S 1.2 0.3 2:58.28 gunicorn 
    70119 root 20 0 1264004 106504 25532 S 1.0 0.3 308:48.43 gunicorn 
    86168 root 20 0 762268 73000 16920 S 1.0 0.2 286:02.25 gunicorn 
    10736 root 20 0 784888 73532 16424 S 0.8 0.2 698:23.85 gunicorn 
    45111 root 20 0 655692 74304 11496 S 0.8 0.2 1250:20 gunicorn 
    45766 root 20 0 763376 73956 16304 S 0.8 0.2 1:58.73 gunicorn 
    45768 root 20 0 763764 74080 16304 S 0.8 0.2 1:58.24 gunicorn 
    48597 root 20 0 761748 72684 16624 S 0.8 0.2 601:45.05 gunicorn 
    51164 root 20 0 785516 73836 16452 S 0.8 0.2 610:05.30 gunicorn 
    69875 root 20 0 764040 74412 16248 S 0.8 0.2 232:01.43 gunicorn 
    77789 root 20 0 761384 71872 16124 S 0.8 0.2 1039:22 gunicorn 
    78970 root 20 0 761388 71992 16144 S 0.8 0.2 1025:46 gunicorn 
    83742 root 20 0 785160 73504 16420 S 0.8 0.2 637:08.82 gunicorn 
    85718 root 20 0 761568 72520 16616 S 0.8 0.2 289:49.45 gunicorn 
    19462 root 20 0 763652 74016 16232 S 0.6 0.2 9:54.89 gunicorn 
    45767 root 20 0 763380 73844 16312 S 0.6 0.2 1:58.08 gunicorn 
    46108 root 20 0 624712 43312 10324 S 0.6 0.1 1:32.70 gunicorn 
    55609 root 20 0 623584 42476 10204 S 0.6 0.1 451:12.10 gunicorn 
    90560 root 20 0 761708 72592 16176 S 0.6 0.2 699:16.52 gunicorn 
    9 root 20 0 0 0 0 S 0.2 0.0 99:47.62 rcu_sched 
    848 root 20 0 305128 6184 4812 S 0.2 0.0 154:31.00 vmtoolsd 
    25374 root 20 0 840960 36396 16280 S 0.2 0.1 0:10.53 containerd 
    39764 root 20 0 933328 109608 32260 S 0.2 0.3 125:28.23 python 
    51465 root 20 0 157904 2420 1572 R 0.2 0.0 0:00.03 top 
    62222 root 20 0 755640 74564 16648 S 0.2 0.2 7:55.19 gunicorn 
    86165 root 20 0 148332 19112 2400 S 0.2 0.1 4:46.62 gunicorn 
    90557 root 20 0 148216 19116 2404 S 0.2 0.1 11:36.28 gunicorn 
    1 root 20 0 193528 6472 3940 S 0.0 0.0 4:31.11 systemd 
    2 root 20 0 0 0 0 S 0.0 0.0 0:02.81 kthreadd 
    

    可见进程 50264 和 62303 占用内存最多,其中50264 占用了68.4%的大内存,总共32G,占用了21G左右,明显不对。

    解决办法:杀死该进程。

    (base) [root@HK-AI ~]# ps -ef|grep 50264
    
    root 50264 50261 2 Sep02 ? 14:45:13 /root/anaconda3/envs/model/bin/python /root/anaconda3/envs/model/bin/gunicorn -b 172.16.1.224:8006 best_raw_feed_main:app -c gunicorn_conf.py -k uvicorn.workers.UvicornWorker --limit-request-line 0
    root 51599 51523 0 14:04 pts/0 00:00:00 grep --color=auto 50264
    (base) [root@HK-AI ~]# kill -9 50264
    (base) [root@HK-AI ~]# free -h
    total used free shared buff/cache available
    Mem: 31G 3.1G 21G 121M 6.2G 27G
    Swap: 15G 0B 15G
    

    内存恢复到27G左右。正常了。

    展开全文
  • 官网:http://valgrind.org/info/about.html 百科介绍:http://baike.baidu.com/link?url=ZdXzff0omzoPpE_yZUlNW9lJxygf5aeJIOp-zjfo9F3wUy3wCAGdXxa3ulOOv2ScfOfa_EVlH5HjWnNbymfCkq 一、引言 二、使用...
    展开全文
  • linux程序内存泄漏排查一、前言​ C/C++的内存操作一直是一种“诟病”,主要就是由于程序员调用API去操作内存的申请和释放,人不是完美的,所以会造成申请完内存不去释放的现象存在;但是内存只申请不释放,到了...

    linux程序内存泄漏排查


    一、前言

    ​ C/C++的内存操作一直是一种“诟病”,主要就是由于程序员调用API去操作内存的申请和释放,人不是完美的,所以会造成申请完内存不去释放的现象存在;

    但是内存只申请不释放,到了一定的阶段,会造成我们的程序崩溃掉;

    ​ 一般我们生产程序跑的时候,我们需要监控内存变化,如果内存可使用大幅度下降,很大概率是由于内存泄漏导致的,这时候,我们需要去定位分析内存泄漏的原因和修复;


    二、案例

    测试案例:

    #include <iostream>
    
    using namespace std;
    
    void GetMemory(char* p,int num)
    {
        p = new char[sizeof(char)*num];
    }
    
    int main()
    {
        char* str = NULL;
        while(1)
        {   
            GetMemory(str,100);
        }
        return 0;
    }
    

    我们使用前面介绍过的命令看一下,内存的变化:

    4332706cda50ba8e5597788a9b9eccf4.png

    通过vmstat命令,我们可以知道free字段在逐渐减少,所以初步可以知道程序;

    三、查找内存泄漏

    1.valgrind

    这是一款开源内存检测的工具,里面包含了很多的工具,一般使用Memcheck这个工具偏多;

    Memcheck:这是valgrind应用最广泛的工具,一个重量级的内存检查器,能够发现开发中绝大多数内存错误使用情况,比如:使用未初始化的内存,使用已经释放了的内存,内存访问越界等。

    注:代码编译时我们要带上参数 -g,有了符号表才可以显示行号这些东西;

    测试代码就是我们上面的代码,我们把while循环注释掉,会更好演示;

    algrind --tool=memcheck --leak-check=full --show-reachable=yes --trace-children=yes ./tt 其中–leak-check=full 指的是完全检查内存泄漏,

    –show-reachable=yes是显示内存泄漏的地点,

    –trace-children=yes是跟入子进程。

    结果:

    0e06024173a59ad476e8db6f86f74e6c.png

    我们会发现在第九行处出现了内存问题;


    2.mtrace

    mtrace能监测程序是否内存泄露

    mtrace需要包含头文件:

    #include <mcheck.h>
    #include <stdlib.h>
    

    步骤:

    1.设置环境变量

    setenv("MALLOC_TRACE", "output", 1);

    2.调用mtrace函数

    mtrace(); 
    

    代码:

    #include <iostream>
    #include <mcheck.h>
    #include <stdlib.h>
    
    using namespace std;
    
    int main()
    {
        setenv("MALLOC_TRACE", "output", 1);  
        mtrace(); 
        char* str = NULL;
        //while(1)
        {   
            char* p  =(char*)malloc(12);
        }
        return 0;
    }
    

    3.编译(带 -g)

    cmake_minimum_required (VERSION 2.8)
    
    project (C++)
    
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g")
    
    add_executable(tt test.cpp)

    4.运行

    ./tt

    5.查看目录下

    root@iZuf67on1pthsuih96udyfZ:~/C++/CMake/C++/Memory/build# ll
    total 60
    drwxr-xr-x 3 root root  4096 Apr  7 15:11 ./
    drwxr-xr-x 3 root root  4096 Apr  7 15:04 ../
    -rw-r--r-- 1 root root 11522 Apr  7 15:04 CMakeCache.txt
    drwxr-xr-x 5 root root  4096 Apr  7 15:04 CMakeFiles/
    -rw-r--r-- 1 root root  1369 Apr  7 15:04 cmake_install.cmake
    -rw-r--r-- 1 root root  4681 Apr  7 15:04 Makefile
    -rw-r--r-- 1 root root   313 Apr  7 15:11 output
    -rwxr-xr-x 1 root root 18992 Apr  7 15:04 tt*

    多了output文件

    6.使用mtrace命令,打开文件

    root@iZuf67on1pthsuih96udyfZ:~/# mtrace test output 
    - 0x0000000001151c20 Free 3 was never alloc'd 0x7f863498ee9d
    - 0x0000000001151d10 Free 4 was never alloc'd 0x7f8634a5991f
    - 0x0000000001151d30 Free 5 was never alloc'd 0x7f8634ac923c
    
    Memory not freed:
    -----------------
               Address     Size     Caller
    0x00000000011521a0      0xc  at /root/C++/CMake/C++/Memory/test.cpp:21

    最终检测到了在21行出现了内存泄漏;

    注:mtrace只能检测new是否有泄漏,但是不能定位在哪一行;


    四、总结

    ​ 作为一名合格的C/C++程序员,在编写程序的时候,我们需要牢记申请和释放内存,不然后造成想象不到的后果;


    想了解学习更多C++后台服务器方面的知识,请关注: 微信公众号:====CPP后台服务器开发====


    展开全文
  • 而且往往问题的源头都比较隐蔽,让人很难排查出问题的根源所在。想要解决这个问题,还得从问题的根源入手。valgrind是一个强大的内存管理工具,常用来检测内存泄漏和内存的非法使用,用好了可以很好的从根源上解决c/...

    c/c++的内存管理一直都是程序猿最头痛的事情,内存越界、数组越界、内存泄漏、内存溢出、野指针、空指针..., 随便一个问题都可能让程序崩溃。而且往往问题的源头都比较隐蔽,让人很难排查出问题的根源所在。

    想要解决这个问题,还得从问题的根源入手。valgrind是一个强大的内存管理工具,常用来检测内存泄漏和内存的非法使用,用好了可以很好的从根源上解决c/c++内存管理的问题。

    1.valgrind的主要功能

    virgrind可以用来检测程序开发中的绝大多数内存,函数、缓存使用、多线程竞争访问内存、堆栈问题,是一个linux下功能非常强大内存检测工具。

    1 valgrind工具

    valgrind-tool= 最常用的选项。运行valgrind中名为toolname的工具。默认memcheck。

    memcheck:这是valgrind应用最广泛的工具,一个重量级的内存检查器,能够发现开发中绝大多数内存错误问题,比如:使用未初始化的内存,使用已经释放了的内存,内存访问越界等。下面将重点介绍此功能。

    callgrind: 主要用来检查程序中函数调用过程中出现的问题。

    cachegrind: 主要用来检查程序中缓存使用出现的问题。

    helgrind: 主要用来检查多线程程序中出现的竞争问题。

    massif: 主要用来检查程序中堆栈使用中出现的问题。

    extension: 可以利用core提供的功能,自己编写特定的内存调试工具。

    2 valgrind memcheck

    2.1memcheck内存检测原理

    valid-value表:

    对于进程的整个地址空间中的每一个字节(byte),都有与之对应的8个bits,对于CPU的每个寄存器,也有一个与之对应的bit向量。这些bits负责记录该字节或者寄存器值是否具有有效的、已经初始化的值。

    valid-Address表:

    对于进程整个地址空间中的一个字节(byte),还有与之对应的1bit,负责记录该地址是否能够被读写。

    内存检测原理:

    当要读写内存中的某个字节时,首先检查这个字节对应的address bit。如果该address bit显示该位置是无效位置,memcheck则报告内存读写错误。valgrind内核相当于一个虚拟的CPU环境,当内存中的某个字节被加载到真实的CPU中时,该字节对应的value bit也被加载到虚拟的CPU环境中,一旦寄存器中的值,被用来产生内存地址,或者该值能够影响程序的输出,则mencheck会检查对应的value bits,如果该值尚未初始化,则会报告使用未初始化内存错误。

    2.2 memcheck内存检测

    2.2.1 准备源码

    创建gdbmem.cpp源码文件,准备待检测的代码如下:

    #include

    #include

    #include

    #include

    #include

    #include

    //memory access overflow

    char* stringcopy(char* psrc)

    {

    int len = strlen(psrc) + 1;

    char* pdst = (char*)malloc(len);//12

    memset(pdst, 0, len * 2);//13

    memcpy(pdst, psrc, len*2);//14

    return pdst;

    }

    //array assess overflow

    void printarray(int arry[], int arrysize)

    {

    int i = 0;

    for(; i < arrysize; i++)

    //for(i = arrysize-1; i >= 0; i--)

    {

    printf("arry[%d]:%d\n",i, arry[i]);

    }

    printf("arry[%d]:%d\n",i+1, arry[i+1]);//27

    }

    //main body

    int main(int narg, const char** args)

    {

    char* pwildptr;

    char* pstr = "this is a memory debug program!\n";

    int array[10] = {1,2,3,4,5,6,7,8,9,10};

    char* ptmp = stringcopy(pstr);//36

    //memory leak

    char* ptmp2 = (char*)malloc(100);//38

    memset(ptmp2, 0, 100);

    // memory write overflow

    printf(ptmp);//41

    // array tip assess overflow

    printarray(array, 10);//43

    free(ptmp);//44

    printf("%p", pwildptr);//45

    //wild ptr copy

    memcpy(ptmp, ptmp2, 20);//47

    printf(ptmp);//48

    return 0;

    }

    2.2.2 编译源码:

    $g++ -g -O0 -c gdbmem.cpp#-g:编译带调试信息的obj文件,-O0:不优化

    $g++ -o gdbmem gdbmem.o

    编译后将在当前目录下生成gdbmem可执行文件。

    2.2.3 valgrind内存检测

    valgring 对gdbmem进行内存检测

    $ valgrind --tool=memcheck --leak-check=full --track-fds=yes ./gdbmem

    ==10668== Memcheck, a memory error detector

    ==10668== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.

    ==10668== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info

    ==10668== Command: ./gdbmem

    ==10668==

    ==10668== Invalid write of size 8

    ==10668== at 0x4C3453F: memset (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)

    ==10668== by 0x40075D: stringcopy(char*) (gdbmem.cpp:13)

    ==10668== by 0x40087A: main (gdbmem.cpp:36)

    ==10668== Address 0x5204060 is 32 bytes inside a block of size 33 alloc'd

    ==10668== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)

    ==10668== by 0x400740: stringcopy(char*) (gdbmem.cpp:12)

    ==10668== by 0x40087A: main (gdbmem.cpp:36)

    ==10668==

    ==10668== Invalid write of size 1

    ==10668== at 0x4C34558: memset (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)

    ==10668== by 0x40075D: stringcopy(char*) (gdbmem.cpp:13)

    ==10668== by 0x40087A: main (gdbmem.cpp:36)

    ==10668== Address 0x5204080 is 16 bytes after a block of size 48 in arena "client"

    ==10668==

    ==10668== Invalid write of size 8

    ==10668== at 0x4C326CB: memcpy@@GLIBC_2.14 (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)

    ==10668== by 0x400778: stringcopy(char*) (gdbmem.cpp:14)

    ==10668== by 0x40087A: main (gdbmem.cpp:36)

    ==10668== Address 0x5204060 is 32 bytes inside a block of size 33 alloc'd

    ==10668== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)

    ==10668== by 0x400740: stringcopy(char*) (gdbmem.cpp:12)

    ==10668== by 0x40087A: main (gdbmem.cpp:36)

    ==10668==

    ==10668== Invalid write of size 2

    ==10668== at 0x4C32723: memcpy@@GLIBC_2.14 (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)

    ==10668== by 0x400778: stringcopy(char*) (gdbmem.cpp:14)

    ==10668== by 0x40087A: main (gdbmem.cpp:36)

    ==10668== Address 0x5204080 is 16 bytes after a block of size 48 in arena "client"

    ==10668==

    this is a memory debug program!

    arry[0]:1

    arry[1]:2

    arry[2]:3

    arry[3]:4

    arry[4]:5

    arry[5]:6

    arry[6]:7

    arry[7]:8

    arry[8]:9

    arry[9]:10

    arry[11]:-623874025

    ==10668== Conditional jump or move depends on uninitialised value(s)

    ==10668== at 0x4E8890E: vfprintf (vfprintf.c:1631)

    ==10668== by 0x4E8F898: printf (printf.c:33)

    ==10668== by 0x4008E6: main (gdbmem.cpp:45)

    ==10668==

    ==10668== Use of uninitialised value of size 8

    ==10668== at 0x4E84711: _itoa_word (_itoa.c:180)

    ==10668== by 0x4E8812C: vfprintf (vfprintf.c:1631)

    ==10668== by 0x4E8F898: printf (printf.c:33)

    ==10668== by 0x4008E6: main (gdbmem.cpp:45)

    ==10668==

    ==10668== Conditional jump or move depends on uninitialised value(s)

    ==10668== at 0x4E84718: _itoa_word (_itoa.c:180)

    ==10668== by 0x4E8812C: vfprintf (vfprintf.c:1631)

    ==10668== by 0x4E8F898: printf (printf.c:33)

    ==10668== by 0x4008E6: main (gdbmem.cpp:45)

    ==10668==

    ==10668== Conditional jump or move depends on uninitialised value(s)

    ==10668== at 0x4E881AF: vfprintf (vfprintf.c:1631)

    ==10668== by 0x4E8F898: printf (printf.c:33)

    ==10668== by 0x4008E6: main (gdbmem.cpp:45)

    ==10668==

    ==10668== Conditional jump or move depends on uninitialised value(s)

    ==10668== at 0x4E87C59: vfprintf (vfprintf.c:1631)

    ==10668== by 0x4E8F898: printf (printf.c:33)

    ==10668== by 0x4008E6: main (gdbmem.cpp:45)

    ==10668==

    ==10668== Conditional jump or move depends on uninitialised value(s)

    ==10668== at 0x4E87CE2: vfprintf (vfprintf.c:1631)

    ==10668== by 0x4E8F898: printf (printf.c:33)

    ==10668== by 0x4008E6: main (gdbmem.cpp:45)

    main函数45行,memcpy(ptmp, ptmp2, 20);读取已经被释放的内存,导致memcheck报错。

    ==10668== Invalid write of size 8

    ==10668== at 0x4C326CB: memcpy@@GLIBC_2.14 (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)

    ==10668== by 0x4008FE: main (gdbmem.cpp:47)

    ==10668== Address 0x5204040 is 0 bytes inside a block of size 33 free'd

    ==10668== at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)

    ==10668== by 0x4008D0: main (gdbmem.cpp:44)

    ==10668== Block was alloc'd at

    ==10668== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)

    ==10668== by 0x400740: stringcopy(char*) (gdbmem.cpp:12)

    ==10668== by 0x40087A: main (gdbmem.cpp:36)

    ==10668==

    ==10668== Invalid write of size 2

    ==10668== at 0x4C32723: memcpy@@GLIBC_2.14 (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)

    ==10668== by 0x4008FE: main (gdbmem.cpp:47)

    ==10668== Address 0x5204050 is 16 bytes inside a block of size 33 free'd

    ==10668== at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)

    ==10668== by 0x4008D0: main (gdbmem.cpp:44)

    ==10668== Block was alloc'd at

    ==10668== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)

    ==10668== by 0x400740: stringcopy(char*) (gdbmem.cpp:12)

    ==10668== by 0x40087A: main (gdbmem.cpp:36)

    ==10668==

    ==10668== Invalid read of size 1

    ==10668== at 0x4ED0760: strchrnul (strchr.S:24)

    ==10668== by 0x4E87207: __find_specmb (printf-parse.h:108)

    ==10668== by 0x4E87207: vfprintf (vfprintf.c:1312)

    ==10668== by 0x4E8F898: printf (printf.c:33)

    ==10668== by 0x40090F: main (gdbmem.cpp:48)

    ==10668== Address 0x5204040 is 0 bytes inside a block of size 33 free'd

    ==10668== at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)

    ==10668== by 0x4008D0: main (gdbmem.cpp:44)

    ==10668== Block was alloc'd at

    ==10668== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)

    ==10668== by 0x400740: stringcopy(char*) (gdbmem.cpp:12)

    ==10668== by 0x40087A: main (gdbmem.cpp:36)

    ==10668==

    ==10668== Invalid read of size 1

    ==10668== at 0x4E8741A: vfprintf (vfprintf.c:1324)

    ==10668== by 0x4E8F898: printf (printf.c:33)

    ==10668== by 0x40090F: main (gdbmem.cpp:48)

    ==10668== Address 0x5204040 is 0 bytes inside a block of size 33 free'd

    ==10668== at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)

    ==10668== by 0x4008D0: main (gdbmem.cpp:44)

    ==10668== Block was alloc'd at

    ==10668== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)

    ==10668== by 0x400740: stringcopy(char*) (gdbmem.cpp:12)

    ==10668== by 0x40087A: main (gdbmem.cpp:36)

    ==10668==

    0x40097d==10668==

    ==10668== FILE DESCRIPTORS: 3 open at exit.

    ==10668== Open file descriptor 2: /dev/pts/4

    ==10668==

    ==10668==

    ==10668== Open file descriptor 1: /dev/pts/4

    ==10668==

    ==10668==

    ==10668== Open file descriptor 0: /dev/pts/4

    ==10668==

    ==10668==

    ==10668==

    ==10668== HEAP SUMMARY:

    ==10668== in use at exit: 100 bytes in 1 blocks

    ==10668== total heap usage: 3 allocs, 2 frees, 1,157 bytes allocated

    ==10668==

    ==10668== 100 bytes in 1 blocks are definitely lost in loss record 1 of 1

    ==10668== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)

    ==10668== by 0x400888: main (gdbmem.cpp:38)

    ==10668==

    ==10668== LEAK SUMMARY:

    ==10668== definitely lost: 100 bytes in 1 blocks

    ==10668== indirectly lost: 0 bytes in 0 blocks

    ==10668== possibly lost: 0 bytes in 0 blocks

    ==10668== still reachable: 0 bytes in 0 blocks

    ==10668== suppressed: 0 bytes in 0 blocks

    ==10668==

    ==10668== For counts of detected and suppressed errors, rerun with: -v

    ==10668== Use --track-origins=yes to see where uninitialised values come from

    ==10668== ERROR SUMMARY: 37 errors from 15 contexts (suppressed: 0 from 0)

    2.2.3 memcheck检测结果分析

    memcheck的LEAK SUMMARY输出结果将内存泄漏分为以下几种情况:

    definitely lost:明确地已经泄漏了,因为在程序运行完的时候,没有指针指向它, 指向它的指针在程序中丢失了

    indirectly lost:间接丢失。当使用了含有指针成员的类或结构时可能会报这个错误。这类错误无需直接修复,他们总是与”definitely lost”一起出现,只要修复”definitely lost”即可。

    possibly lost:发现了一个指向某块内存中部的指针,而不是指向内存块头部。这种指针一般是原先指向内存块头部,后来移动到了内存块的中部,还有可能该指针和该内存根本就没有关系,检测工具只是怀疑有内存泄漏。

    still reachable:可以访问,未丢失但也未释放

    suppressed:已被解决。出现了内存泄露但系统自动处理了。可以无视这类错误。

    内存泄漏概述:

    ==10668== LEAK SUMMARY:

    ==10668== definitely lost: 100 bytes in 1 blocks

    ==10668== indirectly lost: 0 bytes in 0 blocks

    ==10668== possibly lost: 0 bytes in 0 blocks

    ==10668== still reachable: 0 bytes in 0 blocks

    ==10668== suppressed: 0 bytes in 0 blocks

    此处只有100个字节的内存泄漏。

    ==10668== Invalid write of size 8

    ==10668== at 0x4C3453F: memset (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)

    ==10668== by 0x40075D: stringcopy(char*) (gdbmem.cpp:13)

    ==10668== by 0x40087A: main (gdbmem.cpp:36)

    ==10668== Address 0x5204060 is 32 bytes inside a block of size 33 alloc'd

    根据错误提示,stringcopy 函数13行,即memset(pdst, 0, len 2);申请了len的数据长度,memset的时候却使用了2len的数据长度,内存写溢出了。

    ==10668== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)

    ==10668== by 0x400740: stringcopy(char*) (gdbmem.cpp:12)

    ==10668== by 0x40087A: main (gdbmem.cpp:36)

    ==10668==

    ==10668== Invalid write of size 1

    ==10668== at 0x4C34558: memset (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)

    ==10668== by 0x40075D: stringcopy(char*) (gdbmem.cpp:13)

    ==10668== by 0x40087A: main (gdbmem.cpp:36)

    ==10668== Address 0x5204080 is 16 bytes after a block of size 48 in arena "client"

    stringcopy 函数13行,即memset(pdst, 0, len2);申请了len的数据长度,memset的时候却使用了2len的数据长度,内存写溢出。相同语句的内存写溢出,却报了两个错误,原因笔者目前也还没有弄明白,如果有大虾指点,不胜感激。

    ==10668==

    ==10668== Invalid write of size 8

    ==10668== at 0x4C326CB: memcpy@@GLIBC_2.14 (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)

    ==10668== by 0x400778: stringcopy(char*) (gdbmem.cpp:14)

    ==10668== by 0x40087A: main (gdbmem.cpp:36)

    ==10668== Address 0x5204060 is 32 bytes inside a block of size 33 alloc'd

    ==10668== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)

    ==10668== by 0x400740: stringcopy(char*) (gdbmem.cpp:12)

    ==10668== by 0x40087A: main (gdbmem.cpp:36)

    ==10668==

    ==10668== Invalid write of size 2

    ==10668== at 0x4C32723: memcpy@@GLIBC_2.14 (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)

    ==10668== by 0x400778: stringcopy(char*) (gdbmem.cpp:14)

    ==10668== by 0x40087A: main (gdbmem.cpp:36)

    ==10668== Address 0x5204080 is 16 bytes after a block of size 48 in arena "client"

    stringcopy 函数13行,即memcpy(pdst, psrc, len2);申请了len的数据长度,memset的时候却使用了2len的数据长度,内存写溢出。

    ==10668==

    this is a memory debug program!

    arry[0]:1

    arry[1]:2

    arry[2]:3

    arry[3]:4

    arry[4]:5

    arry[5]:6

    arry[6]:7

    arry[7]:8

    arry[8]:9

    arry[9]:10

    arry[11]:-623874025

    ==10668== Conditional jump or move depends on uninitialised value(s)

    ==10668== at 0x4E8890E: vfprintf (vfprintf.c:1631)

    ==10668== by 0x4E8F898: printf (printf.c:33)

    ==10668== by 0x4008E6: main (gdbmem.cpp:45)

    ==10668==

    ==10668== Use of uninitialised value of size 8

    ==10668== at 0x4E84711: _itoa_word (_itoa.c:180)

    ==10668== by 0x4E8812C: vfprintf (vfprintf.c:1631)

    ==10668== by 0x4E8F898: printf (printf.c:33)

    ==10668== by 0x4008E6: main (gdbmem.cpp:45)

    ==10668==

    ==10668== Conditional jump or move depends on uninitialised value(s)

    ==10668== at 0x4E84718: _itoa_word (_itoa.c:180)

    ==10668== by 0x4E8812C: vfprintf (vfprintf.c:1631)

    ==10668== by 0x4E8F898: printf (printf.c:33)

    ==10668== by 0x4008E6: main (gdbmem.cpp:45)

    ==10668==

    ==10668== Conditional jump or move depends on uninitialised value(s)

    ==10668== at 0x4E881AF: vfprintf (vfprintf.c:1631)

    ==10668== by 0x4E8F898: printf (printf.c:33)

    ==10668== by 0x4008E6: main (gdbmem.cpp:45)

    ==10668==

    ==10668== Conditional jump or move depends on uninitialised value(s)

    ==10668== at 0x4E87C59: vfprintf (vfprintf.c:1631)

    ==10668== by 0x4E8F898: printf (printf.c:33)

    ==10668== by 0x4008E6: main (gdbmem.cpp:45)

    ==10668==

    ==10668== Conditional jump or move depends on uninitialised value(s)

    ==10668== at 0x4E87CE2: vfprintf (vfprintf.c:1631)

    ==10668== by 0x4E8F898: printf (printf.c:33)

    ==10668== by 0x4008E6: main (gdbmem.cpp:45)

    main函数45行,printf("%p", pwildptr);读取未初始化的野指针

    ==10668==

    ==10668== Invalid write of size 8

    ==10668== at 0x4C326CB: memcpy@@GLIBC_2.14 (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)

    ==10668== by 0x4008FE: main (gdbmem.cpp:47)

    ==10668== Address 0x5204040 is 0 bytes inside a block of size 33 free'd

    ==10668== at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)

    ==10668== by 0x4008D0: main (gdbmem.cpp:44)

    ==10668== Block was alloc'd at

    ==10668== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)

    ==10668== by 0x400740: stringcopy(char*) (gdbmem.cpp:12)

    ==10668== by 0x40087A: main (gdbmem.cpp:36)

    ==10668==

    ==10668== Invalid write of size 2

    ==10668== at 0x4C32723: memcpy@@GLIBC_2.14 (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)

    ==10668== by 0x4008FE: main (gdbmem.cpp:47)

    ==10668== Address 0x5204050 is 16 bytes inside a block of size 33 free'd

    ==10668== at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)

    ==10668== by 0x4008D0: main (gdbmem.cpp:44)

    ==10668== Block was alloc'd at

    ==10668== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)

    ==10668== by 0x400740: stringcopy(char*) (gdbmem.cpp:12)

    ==10668== by 0x40087A: main (gdbmem.cpp:36)

    main函数47行,memcpy(ptmp, ptmp2, 20);写入已经释放的内存

    ==10668==

    ==10668== Invalid read of size 1

    ==10668== at 0x4ED0760: strchrnul (strchr.S:24)

    ==10668== by 0x4E87207: __find_specmb (printf-parse.h:108)

    ==10668== by 0x4E87207: vfprintf (vfprintf.c:1312)

    ==10668== by 0x4E8F898: printf (printf.c:33)

    ==10668== by 0x40090F: main (gdbmem.cpp:48)

    ==10668== Address 0x5204040 is 0 bytes inside a block of size 33 free'd

    ==10668== at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)

    ==10668== by 0x4008D0: main (gdbmem.cpp:44)

    ==10668== Block was alloc'd at

    ==10668== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)

    ==10668== by 0x400740: stringcopy(char*) (gdbmem.cpp:12)

    ==10668== by 0x40087A: main (gdbmem.cpp:36)

    ==10668==

    ==10668== Invalid read of size 1

    ==10668== at 0x4E8741A: vfprintf (vfprintf.c:1324)

    ==10668== by 0x4E8F898: printf (printf.c:33)

    ==10668== by 0x40090F: main (gdbmem.cpp:48)

    ==10668== Address 0x5204040 is 0 bytes inside a block of size 33 free'd

    ==10668== at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)

    ==10668== by 0x4008D0: main (gdbmem.cpp:44)

    ==10668== Block was alloc'd at

    ==10668== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)

    ==10668== by 0x400740: stringcopy(char*) (gdbmem.cpp:12)

    ==10668== by 0x40087A: main (gdbmem.cpp:36)

    main函数47行,printf(ptmp);写入已经释放的内存

    0x40097d==10668==

    ==10668== FILE DESCRIPTORS: 3 open at exit.

    ==10668== Open file descriptor 2: /dev/pts/4

    ==10668==

    ==10668==

    ==10668== Open file descriptor 1: /dev/pts/4

    ==10668==

    ==10668==

    ==10668== Open file descriptor 0: /dev/pts/4

    ==10668==

    linux为了实现一切皆文件的设计哲学,不仅将数据抽象成了文件,也将一切操作和资源抽象成了文件,比如说硬件设备,socket,磁盘,进程,线程等。

    这样的设计将系统的所有动作都统一起来,实现了对系统的原子化操作,大大降低了维护和操作的难度。

    设备描述符,就是描述该文件数据设备的唯一标示,不同类型的文件,文件描述符也不一样,如下所示:

    ==10668==

    ==10668==

    ==10668== HEAP SUMMARY:

    ==10668== in use at exit: 100 bytes in 1 blocks

    ==10668== total heap usage: 3 allocs, 2 frees, 1,157 bytes allocated

    ==10668==

    ==10668== 100 bytes in 1 blocks are definitely lost in loss record 1 of 1

    ==10668== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)

    ==10668== by 0x400888: main (gdbmem.cpp:38)

    ==10668==

    内存泄漏概述,3次内存分配,两次释放。已经有100个字节的内存已经确定泄漏。泄漏的内存分配于38行,charptmp2 = (char)malloc(100);至此,内存泄漏检测完毕。

    valgrind内存检测解析

    valgrind对内存读写溢出,读取未初始化的变量、指针、内存能够很好的检测到,但是对于数组越界却无法检测,这是因为memcheck并不对stack和全局数组进行越界检查,所以无法检测出printarray中的内存访问越界。

    展开全文
  • Linux占用内存排查

    2021-01-20 17:04:16
    查看内存的占用情况,然后键入"M"命令根据内存的占用情况降序排列("P"是CPU占用情况降序排列)2.关闭掉不需要的进程,3.再使用top查看内存占用情况,发觉内存占用率已经降下来了,但是free -g却还有100G被占用(内存...
  • 【赛迪网报道】Linux系统下真正有危害的是内存泄漏的堆积,这会最终消耗尽系统任何的内存。下面是排查和解决方案与大家一起分享。1、Linux 内存监控内存泄漏的定义:一般我们常说的内存泄漏是指堆内存的泄漏。堆内存...
  • 使用java springboot开发了一个项目来调用cdp4j来操作chrome浏览器,但是调用浏览器访问页面越多,占用内存就越大,直到内存溢出这就是典型的调用第三方框架,导致的内存溢出,而并不清楚第三方框架中哪个代码导致了...
  • linux内存故障排查

    2020-08-23 17:32:52
    上周五,在测试的一台服务器上频繁出现系统内存不够,进程被kill的现象。原以为是开源软件或自研软件内存泄漏导致的,可查看内存信息发现很奇怪,一台16GB的机器,进程总共就占了不到6GB,但memfree的内存只有160MB...
  • Linux系统下真正有危害的是内存泄漏的堆积,这会最终消耗尽系统任何的内存。下面是排查和解决方案与大家一起分享。1、Linux 内存监控内存泄漏的定义:一般我们常说的内存泄漏是指堆内存的泄漏。堆内存是指程式从堆中...
  • linux内存排查

    千次阅读 2015-07-13 17:24:57
    已发现2个内存错误,应用名称(kernel:),日志内容(hangzhou-jishuan-DDS0248 kernel: sbridge: HANDLING MCE MEMORY ERROR hangzhou-jishuan-DDS0248 kernel: EDAC MC0: CE row 5, channel 0, label CPU_SrcID#0_...
  • linux程序内存泄漏排查一、前言 C/C++的内存操作一直是一种“诟病”,主要就是由于程序员调用API去操作内存的申请和释放,人不是完美的,所以会造成申请完内存不去释放的现象存在;但是内存只申请不释放,到了一定...
  • 首先,这台服务器是我们的打印服务器,使用的是finereport7.0自带的webreport程序背景是自从发布了一个供应商包装打印的功能后打印服务器经常内存溢出首先在配置层面在系统启动时需要加上参数:-XX:+...
  • 非0的时候,它会扫描进程队列,然后将可能导致内存溢出的进程杀掉,也就是占用内存最大的那个,但是设置为0的时候,它只杀掉导致oom的那个进程,避免了进程队列的扫描 ,但是释放的内存大小有限 (3)、oom_dump_...
  • 背景线上两台 OpenResty 占用内存过高,8c32G 的机器用了 28G 内存,总觉得不正常,使用简单的重启大法,并没什么用处,今天刚好排查一下。free[root@iZ1w4igf11Zconf]#free-gtotalusedfreesharedbufferscachedMem:....
  • 标题:JAVA线上故障排查全套路作者:fredalxin地址:https://fredal.xin/java-error-check线上故障主要会包括cpu、磁盘、内存以及网络问题,而大多数故障可能会包含不止一个层面的问题,所以进行排查时候尽量四个...
  • 线上故障主要会包括cpu、磁盘、内存以及网络问题,而大多数故障可能会包含不止一个层面的问题,所以进行排查时候尽量四个方面依次排查一遍。同时例如jstack、jmap等工具也是不囿于一个方面的问题的,基本上出问题...
  • 如果出现这种现象可行代码排查:一)是否应用中的类中和引用变量过多使用了Static修饰 如public staitc Student s;在类中的属性中使用 static修饰的最好只用基本类型或字符串。如public static int i = 0; //public ...
  • 实例进程由于占用内存达到linux系统的最大阈值,导致linux系统kill了mysql实例进程,可以通过如下方式查看mysql使用了多少内存: 查看每个线程占用多少内存,然后乘以正在运行的线程(也就是排查sleep的)。...
  • 作者:fredalxin线上故障主要会包括 CPU、磁盘、内存以及网络问题,而大多数故障可能会包含不止一个层面的问题,所以进行排查时候尽量四个方面依次排查一遍。同时例如 jstack、jmap 等工具也是不囿于一个方面的问题...
  • fredalxin|https://sourl.cn/duWZhd线上故障主要会包括 cpu、磁盘、内存以及 网络 问题,而大多数故障可能会包含不止一个层面的问题,所以进行排查时候尽量四个方面依次排查一遍。同时例如 jstack 、jmap 等工具也是...
  • Linux系统排查内存篇  常见工作中,计算机系统的资源主要包括CPU,内存,硬盘以及网络,过度使用这些资源将使系统陷入困境。本系列一共四篇博文,结合我在实习期间的学习,介绍一些常见的Linux系统排障工具及方法...
  • linux内存过高排查

    2019-10-02 00:12:28
    启动程序时,无法正常启动,程序直接没有 被系统kill(dmesg | egrep -i -B100 'killed process'), 发现 shared memory , cache 占用过高 常用的命令: ...在系统中除了内存将被耗尽的时候...
  • linux排查内存泄漏

    2019-07-03 15:32:17
    Memcheck是valgrind应用最广泛的工具,一个重量级的内存检查器,能够发现开发中绝大多数内存错误使用情况,比如:使用未初始化的内存,使用已经释放了的内存内存访问越界等。 使用示例: #include <stdio.h&...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 889
精华内容 355
关键字:

linux内存排查

linux 订阅