Linuxのメモリ使用量とメモリリークケース

1.メモリ使用状況の分析

http://www.360doc.com/content/15/1118/13/17283_514054063.shtml

https://www.linuxidc.com/Linux/2016-04/130069.htm

総メモリシステムの1.1分析

猫の/ proc / meminfoにすることで、利用可能な物理メモリ= MEMFREE +バッファ+キャッシュ。

MemTotal:5933132 kBの
MEMFREE:4485932 kBの
MemAvailable:4822944 kBの
バッファ:122148 kBの
キャッシュ:630048キロバイト
SwapCached:0 kBの
アクティブ:806136 kBの
非アクティブ:461288 kBの
アクティブ(アノン):516344 kBの
非アクティブ(アノン):230112 kBの
アクティブ(ファイル) :289792 kBの
非アクティブ(ファイル):231176 kBの
Unevictable:32キロバイト
Mlocked:32キロバイト
SwapTotal:7999484 kBの
SwapFree:7999484 kBの
ダーティ:204 kBの
書き戻し:0 kBの
AnonPages:515264キロバイト
...

エコー3> / proc / sys / vm / drop_cachesと、キャッシュシステムをクリーンアップします。

これに書き込むと、カーネルが自由になるためにそのメモリを引き起こして、メモリからクリーンなキャッシュ、dentriesとiノードをドロップするようになります。

フリーページキャッシュ1に、フリーdentries及びiノード2から、フリーページキャッシュ3に、dentries及びiノード。

1.2プロセスのメモリ分析

猫の/ proc / {PID} /マップ

メモリリークの2.1タイプ

1.再発メモリリーク
メモリリークにつながるたびに実行されたときにコードメモリリークが、複数回実行することができます

2.エピソードメモリリーク
コードメモリリークは、特定の環境またはプロセス動作が発生するだけで起こります。散発的な再発と対向しています。特定の環境では、散発的には、おそらくそれは、多くの場合で作られてしまいます。だから、テスト環境と試験方法は、メモリリークを検出することが重要です

3.ワンタイムメモリリーク
コードメモリリークが一度だけ実行され、又はによるアルゴリズムの欠陥に存在常に1であり、唯一のメモリリークの原因

4.暗黙のメモリリークが
動作中に、だけ空きメモリの終わりまで常に割り当てメモリをプログラムします。厳密に言えば、メモリリークは、すべてのアプリケーションの最終的なプログラムメモリの解放ので、ここでは発生しませんでした。しかし、サーバープログラムのために、あなたはタイムリーなメモリを解放していない、数日、数週間、あるいは数ヶ月、数を実行するために必要な、すべてのメモリが最終的にシステムが不足する原因になります。そこで、我々は、暗黙的なメモリリークのメモリリークのこのタイプを呼び出します

2.2一般的なメモリリーク検出ツール

C / C ++
1. Valgrindは:デバッグとCとCで書かれたプログラムを目指し、Linuxプログラムをプロファイリング++ 
2. ccmalloc:LinuxおよびSolaris上のCおよびC ++プログラムの使用メモリリークとmallocのデバッグライブラリに簡単に 
3. LeakTracer:C ++メモリリークで追跡および分析プログラムの下でのLinux、SolarisおよびHP-UX 
4.電気柵:ブルース・ペレンズmalloc関数によって書かれたLinuxディストリビューションのバージョン()デバッグライブラリ 
5.漏れ:Linuxのメモリリークが検出されました 
6. Dmalloc:デバッグmallocの図書館 
7. MEMWATCH:ヨハンLindhによって書かれたが、主のGCC precessorによって行わ、オープンソースC言語メモリエラー検出ツールであります 
8. KCachegrind:CachegrindとCalltreeによって生成されたプロファイリングデータの可視化ツール 

2.3原理メモリテスト

3.1 Linuxカーネルのメモリリーク検出kmemleak

kmemleanは、オブジェクトがメモリ/ SYS /カーネル/デバッグ/ kmemleakに記録する際に放出されていないカーネルメモリの漏れを検出するための方法が提供されます。

3.1.1 kmemleakを有効にします

CONFIG_DEBUG_KMEMLEAK = Y
CONFIG_DEBUG_KMEMLEAK_EARLY_LOG_SIZE = 400
#CONFIG_DEBUG_KMEMLEAK_TESTが設定されていません
オープンCONFIG_DEBUG_KMEMLEAK_DEFAULT_OFFデフォルト= N ----------

あなたは合理化されたバージョンを使用して、オープンKMEMLEAK_FULLをしない場合。メモリのフルバージョンより消費、組み込みのデバッグに適した合理化バージョン。

3.1.2コンフィギュレーション取得kmemleak結果

設定パラメータ:

コードをコピー
無効kmemleakオフ(不可逆性)
スタックスタック=(デフォルト)タスクのスキャンを有効に
スタックスタック=無効スキャンタスクオフ
メモリ上のスキャン=が自動的にスレッドをスキャンを開始(デフォルト)
=オフスキャン自動的にメモリスキャンスレッドを停止
n秒スキャン内に配置されたスキャン= <秒>自動メモリ
オープンスキャンスキャンカーネル
明確な明確なメモリリークレポート
ダンプ= <ADDR>ダンプ情報オブジェクト<ADDR>
「kmemleak = OFF」することで、あなたも無効にKmemleakあなたは、カーネルコマンドラインを起動することができるとき。初期化kmemleak、メモリの割り当てまたはこれらのアクションのリリース前にログバッファに予め記憶されています。CONFIG_DEBUG_KMEMLEAK_EARLY_LOG_SIZE設定とを介してバッファのサイズ。
コードをコピー
猫/ SYS /カーネル/デバッグ/ kmemleak> kmemleak.txt

3.1.3分析kmemleak漏れ

参照文献:

Kmemleakの使用

Linuxのカーネルメモリリークの検出

Linuxのメモリリークの検出

3.2 valgrindの

LinuxのC / C ++メモリリーク検出ツール

Linuxのメモリリークチェックツールの下にいくつかのプログラム

いくつかのメモリリークチェックツールの下にLinuxのC ++プログラム

Linuxのメモリリークの検出技術

アプリケーションメモリの問題Linuxのプログラムを見つけるvalgrindの

 

プログラムメモリ空間を表示するには、2つの方法

ビューの/ proc / {PIDは} /ファイルをマップ

 

二、のpmapコマンドは、原理は同じです

[ルート情報@〜]#のpmapの1013

 

メモリリークは何である
メモリリークは、プログラムがこのメモリにオペレーティングシステムを再利用することができない、その結果、放出された後使用されていないダイナミックメモリのアプリケーションを指します。
たとえば、このプログラムは、メモリリークの4つのバイトがあり、スペースの4バイトのために適用されるが、解放されませんでした。

書式#include <iostreamの>
名前空間stdを使用。

メインINT()
{
int型* P新しい新しいINT =(1);
COUT * P << << ENDL;
戻り0
}

、時間とともに、より多くのメモリリーク、少なくメモリが利用可能で、光システムクラッシュにしつつ性能が損なわれる。

メモリリークが発生した場合、一般的に、リークが再起動メモリに回収することができます。しかし、Linuxの場合、通常はサーバープログラムを実行し、再起動して自由にすることはできません、我々はメモリリークで注意しなければなりません。

これは、メモリリークが特徴
暴露する前に十分な長さの時間を実行するために-再現することは困難です。

難しい見つけます - 間違った位置をランダムであり、コードとメモリリークが任意の接触を持って見ることができません。

最も簡単な方法は
避けるのメモリリークには、プログラムを書くことで、通常はこのようなプログラムの規範があり、プログラムを書くとき、ペアでのリリースを適用するために私たちを必要とします。それに対応したリリースが存在する必要があり、各アプリケーションを意味するので。

この機能に基づいて、簡単な方法は、異なるアプリケーションとリリースの数が、メモリリークであるとみなされた場合、アプリケーションの数やコードのリリースを数えることです。

#include "stdio.hの"
の#include "STDLIB.H"

int型malloc_count、free_count。

ボイド* my_malloc(int型のサイズ)
{
malloc_count ++;
サイズ)はmallocを返す;
}
ボイドmy_free(ボイド* P)
{
free_count ++;
フリー(P);
}
(INTメイン)
{
COUNT = 0;
INT * P1 =(INT *) my_malloc(sizeif(INT))
INT * P2 =(INT *)my_malloc(sizeif(INT))
のprintf( "%のDは、%D"、P1、P2);
my_free(P1);
IF(!malloc_count = free_count)
のprintf (「メモリリーク\ N-!」)
の戻り0
}

分析するための
利点を:
直感的に簡単に理解するために、実装が容易

短所:
1の操作により、このメソッドを生成し、分析の最後に実行印刷結果を知ることが必要です。

2.この方法では、パッケージのそのすべてのスペースと解除機能を必要とし、呼び出しの時点でカプセル化された関数呼び出しを修正します。C /リリースメモリインタフェース内のアプリケーションはあまりありませんが、大規模なプロジェクトのために、これらのインタフェースへのローカル電話がたくさんありますが、すべての作業を比較的多量で交換します。

3.唯一のC言語に適用され、それがCで使用することはできません++

4.ライブラリの呼び出しには適用されません。あなたがライブラリに適用する場合は、ライブラリーは、コードを変更する必要があります

唯一の具体的な情報は、どのくらいのスペースリークとして、リークを検出しないが、

6.説明漏洩ラインによって引き起こさされていません

 

Linuxのメモリリーク検出

1. valgrindのインストール:
  これは、メモリ割り当て関数(malloc関数、reallocの、あるmemalign、フリーとしてMTRACE、オープンソースプログラムメモリ検出ツールで ) インストールフック関数。トレース情報記憶アプリケーションとこれらのレコードフック関数のリリース。

詳細Valgrindは:

 

:Valgrindのは、以下のツールの一部が含ま
1.Memcheckを:初期化されていないの使用:これは、最も広く使用されているツールValgrindは、メモリー・チェッカーのヘビー級である、など、状況はメモリエラーの使用の大半に開発することができることが判明し
2.callgrind :主に呼び出す関数で検査プログラムの過程で生じる問題のために使用されている
3.cachegrind:それは主にプロシージャキャッシュを使用して問題をチェックするために使用されて表示されます
4.Helgrind:主に懸念が複数のスレッドから発生する競争をチェックするために使用される
5。山塊:主に使用から生じるプログラム・スタックの問題をチェックするために使用され
6.Extensionを:あなたは、あなたがあなた自身の特定のメモリデバッグツールを書くことができる機能のコアを使用することができます
2.mtraceコマンドを

男3 MTRACEはmanページに機能を表示することができます


MTRACEもの使用に対応するコマンドを、持っています:
所望の出力ファイルのパス名にMALLOC_TRACE環境変数

 

二.在需要检测的源代码中引入mcheck.h头文件
1.在分配内存之前调用mtrace(); ,一般在main函数的开头调用
2.在结束检测的地方调用muntrace(); ,一般在return之前调用
3.编译程序时需要加上-g 选项
#include <stdio.h>
#include <malloc.h>
#include <mcheck.h>
int main()
{
mtrace();
int *p = NULL;
p =(int *)malloc(sizeof(int) * 1);
//free(p);//未free,内存泄漏
muntrace();
return 0;
}


4.内存泄漏信息将在MALLOC_TRACE环境变量指定的文件中报告,需要使用mtrace命令将信息转换。

Valgrind的最新版是3.11.0,它一般包含下列工具: 

1.Memcheck 

    最常用的工具,用来检测程序中出现的内存问题,所有对内存的读写都会被检测到,一切对malloc()/free()/new/delete的调用都会被捕获。所以,它能检测以下问题: 

    对未初始化内存的使用; 

    读/写释放后的内存块; 

    读/写超出malloc分配的内存块; 

    读/写不适当的栈中内存块; 

    内存泄漏,指向一块内存的指针永远丢失; 

    不正确的malloc/free或new/delete匹配; 

    memcpy()相关函数中的dst和src指针重叠。 

2.Callgrind 

    和gprof类似的分析工具,但它对程序的运行观察更是入微,能给我们提供更多的信息。和gprof不同,它不需要在编译源代码时附加特殊选项,但加上调试选项是推荐的。Callgrind收集程序运行时的一些数据,建立函数调用关系图,还可以有选择地进行cache模拟。在运行结束时,它会把分析数据写入一个文件。callgrind_annotate可以把这个文件的内容转化成可读的形式。 

3.Cachegrind 

    Cache分析器,它模拟CPU中的一级缓存I1,Dl和二级缓存,能够精确地指出程序中cache的丢失和命中。如果需要,它还能够为我们提供cache丢失次数,内存引用次数,以及每行代码,每个函数,每个模块,整个程序产生的指令数。这对优化程序有很大的帮助。 

4.Helgrind 

    它主要用来检查多线程程序中出现的竞争问题。Helgrind寻找内存中被多个线程访问,而又没有一贯加锁的区域,这些区域往往是线程之间失去同步的地方,而且会导致难以发掘的错误。Helgrind实现了名为“Eraser”的竞争检测算法,并做了进一步改进,减少了报告错误的次数。不过,Helgrind仍然处于实验阶段。 

5.Massif 

    堆栈分析器,它能测量程序在堆栈中使用了多少内存,告诉我们堆块,堆管理块和栈的大小。Massif能帮助我们减少内存的使用,在带有虚拟内存的现代系统中,它还能够加速我们程序的运行,减少程序停留在交换区中的几率。 

此外,lackey和nulgrind也会提供。Lackey是小型工具,很少用到;Nulgrind只是为开发者展示如何创建一个工具。

1.3 原理

Memcheck 能够检测出内存问题,关键在于其建立了两个全局表。Valid-Value 表

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

Valid-Address 表

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

检测原理:

当要读写内存中某个字节时,首先检查这个字节对应的 A bit。如果该A bit显示该位置是无效位置,memcheck则报告读写错误。

内核(core)类似于一个虚拟的 CPU 环境,这样当内存中的某个字节被加载到真实的 CPU 中时,该字节对应的 V bit 也被加载到虚拟的 CPU 环境中。一旦寄存器中的值,被用来产生内存地址,或者该值能够影响程序输出,则 memcheck 会检查对应的V bits,如果该值尚未初始化,则会报告使用未初始化内存错误。

2 安装使用

2.1安装

从官网http://www.valgrind.org下载最新版本(当前3.11)

#tar xvf valgrind-3.11.1.tar.bz2
#cd valgrind-3.11.1
#./configure --prefix=/usr/local/valgrind--指定安装目录
#make
#make install

2.2 命令介绍

用法:valgrind[options] prog-and-args [options]: 常用选项,适用于所有Valgrind工具

  1. -tool=<name> 最常用的选项。运行 valgrind中名为toolname的工具。默认memcheck。
  2. h –help 显示帮助信息。
  3. -version 显示valgrind内核的版本,每个工具都有各自的版本。
  4. q –quiet 安静地运行,只打印错误信息。
  5. v –verbose 更详细的信息, 增加错误数统计。
  6. -trace-children=no|yes 跟踪子线程? [no]
  7. -track-fds=no|yes 跟踪打开的文件描述?[no]
  8. -time-stamp=no|yes 增加时间戳到LOG信息? [no]
  9. -log-fd=<number> 输出LOG到描述符文件 [2=stderr]
  10. -log-file=<file> 将输出的信息写入到filename.PID的文件里,PID是运行程序的进行ID
  11. -log-file-exactly=<file> 输出LOG信息到 file
  12. -log-file-qualifier=<VAR> 取得环境变量的值来做为输出信息的文件名。 [none]
  13. -log-socket=ipaddr:port 输出LOG到socket ,ipaddr:port

LOG信息输出:

  1. -xml=yes 将信息以xml格式输出,只有memcheck可用
  2. -num-callers=<number> show <number> callers in stack traces [12]
  3. -error-limit=no|yes 如果太多错误,则停止显示新错误? [yes]
  4. -error-exitcode=<number> 如果发现错误则返回错误代码 [0=disable]
  5. -db-attach=no|yes 当出现错误,valgrind会自动启动调试器gdb。[no]
  6. -db-command=<command> 启动调试器的命令行选项[gdb -nw %f %p]

适用于Memcheck工具的相关选项:

  1. -leak-check=no|summary|full 要求对leak给出详细信息? [summary]
  2. -leak-resolution=low|med|high how much bt merging in leak check [low]
  3. -show-reachable=no|yes show reachable blocks in leak check? [no]

http://www.360doc.com/content/15/1118/13/17283_514054063.shtml

https://www.linuxidc.com/Linux/2016-04/130069.htm

1.1 系统总内存分析

通过cat /proc/meminfo,可用的物理内存=MemFree+Buffers+Cached。

MemTotal:        5933132 kB
MemFree:         4485932 kB
MemAvailable:    4822944 kB
Buffers:          122148 kB
Cached:           630048 kB
SwapCached:            0 kB
Active:           806136 kB
Inactive:         461288 kB
Active(anon):     516344 kB
Inactive(anon):   230112 kB
Active(file):     289792 kB
Inactive(file):   231176 kB
Unevictable:          32 kB
Mlocked:              32 kB
SwapTotal:       7999484 kB
SwapFree:        7999484 kB
Dirty:               204 kB
Writeback:             0 kB
AnonPages:        515264 kB

echo 3 > /proc/sys/vm/drop_caches,会清理系统的cache。

Writing to this will cause the kernel to drop clean caches, dentries and inodes from memory, causing that memory to become free.

1-to free pagecache, 2-to free dentries and inodes, 3-to free pagecache, dentries and inodes。

1.2 进程内存分析

cat /proc/{pid}/maps

2.1 内存泄露类型

1. 常发性内存泄漏
发生内存泄漏的代码会被多次执行到,每次被执行的时候都会导致一块内存泄漏

2. 偶发性内存泄漏
发生内存泄漏的代码只有在某些特定环境或操作过程下才会发生。常发性和偶发性是相对的。对于特定的环境,偶发性的也许就变成了常发性的。所以测试环境和测试方法对检测内存泄漏至关重要

3. 一次性内存泄漏
发生内存泄漏的代码只会被执行一次,或者由于算法上的缺陷,导致总会有一块且仅有一块内存发生泄漏

4. 隐式内存泄漏
程序在运行过程中不停的分配内存,但是直到结束的时候才释放内存。严格的说这里并没有发生内存泄漏,因为最终程序释放了所有申请的内存。但是对于一个服务器程序,需要运行几天,几周甚至几个月,不及时释放内存也可能导致最终耗尽系统的所有内存。所以,我们称这类内存泄漏为隐式内存泄漏

2.2 常用内存泄露检测工具

C/C++
1. Valgrind: Debugging and profiling Linux programs, aiming at programs written in C and C++ 
2. ccmalloc: Linux和Solaris下对C和C++程序的简单的使用内存泄漏和malloc调试库 
3. LeakTracer: Linux、Solaris和HP-UX下跟踪和分析C++程序中的内存泄漏 
4. Electric Fence: Linux分发版中由Bruce Perens编写的malloc()调试库 
5. Leaky: Linux下检测内存泄漏的程序 
6. Dmalloc: Debug Malloc Library 
7. MEMWATCH: 由Johan Lindh编写,是一个开放源代码C语言内存错误检测工具,主要是通过gcc的precessor来进行 
8. KCachegrind: A visualization tool for the profiling data generated by Cachegrind and Calltree 

2.3 内存检测原理

3.1 Linux内核内存泄漏检测kmemleak

kmemlean提供了一种检测内核内存泄露的方法,当内存对象没有被释放是,将其记录在/sys/kernel/debug/kmemleak中。

3.1.1 使能kmemleak

CONFIG_DEBUG_KMEMLEAK=y
CONFIG_DEBUG_KMEMLEAK_EARLY_LOG_SIZE=400
# CONFIG_DEBUG_KMEMLEAK_TEST is not set
CONFIG_DEBUG_KMEMLEAK_DEFAULT_OFF=n----------默认打开

如果没有打开KMEMLEAK_FULL,则使用了精简版。完整版比较耗内存,精简版适合嵌入式调试。

3.1.2 配置获取kmemleak结果

参数配置:

コードをコピー
off 禁用kmemleak(不可逆)
stack=on 启用任务堆栈扫描(default)
stack=off 禁用任务堆栈扫描
scan=on 启动自动记忆扫描线程(default)
scan=off 停止自动记忆扫描线程
scan=<secs> 设置n秒内自动记忆扫描
scan 开启内核扫描
clear 清除内存泄露报告
dump=<addr> 转存信息对象在<addr>
通过“kmemleak = OFF”,也可以在启动时禁用Kmemleak在内核命令行。在初始化kmemleak之前,内存的分配或释放这些动作被存储在一个前期日志缓冲区。这个缓冲区的大小通过配CONFIG_DEBUG_KMEMLEAK_EARLY_LOG_SIZE设置。 
コードをコピー
cat /sys/kernel/debug/kmemleak > kmemleak.txt

3.1.3 分析kmemleak泄漏情况

参考文档:

kmemleak的使用

Linux Kernel Memory Leak Detection

Linux memory leak detection

3.2 valgrind

Linux C/C++ Memory Leak Detection Tool

Linux 下几款程序内存泄漏检查工具

Linux下几款C++程序中的内存泄露检查工具

Linux 内存泄露检测技巧

应用 Valgrind 发现 Linux 程序的内存问题

 

查看程序内存空间两种方法

一、查看/proc/{pid}/maps文件

 

二、pmap命令,原理上是一样的

[root@info ~]# pmap 1013

 

什么是内存泄漏
内存泄漏是指程序动态申请的内存在使用完后没有释放,导致这段内存不能被操作系统回收再利用。
例如这段程序,申请了4个字节的空间但没有释放,有4个字节的内存泄漏。

#include <iostream>
using namespace std;

int main()
{
int *p = new int(1);
cout <<*p<<endl;
return 0
}

随着时间的推移,泄漏的内存越来越多,可用的内存越来越少,轻则性能受损,重则系统崩溃。

一般情况下,发生内存泄漏时,重启就可以回收泄漏的内存。但是对于linux,通常跑的是服务器程序,不可以随意重启,在内存泄漏问题上就要格外小心。

内存泄漏特点
难复现 — 要运行到足够长的时间才会暴露。

难定位 — 出错位置是随机的,看不出与内存泄漏的代码有什么联系。

最简单的方法
为了避免写出内存泄漏的程序,通常会有这样的编程规范,要求我们在写程序时申请和释放成对出现的。因为每一次申请都意味着必须有一次释放与它相对应。

基于这个特点,一种简单的方法就是在代码中统计申请和释放的次数,如果申请和释放的数量不同,就认为是内存泄漏了。

#include "stdio.h"
#include "stdlib.h"

int malloc_count, free_count;

void * my_malloc(int size)
{
malloc_count++;
return malloc(size);
}
void my_free(void *p)
{
free_count++;
free(p);
}
int main()
{
count = 0;
int *p1 = (int *)my_malloc(sizeif(int))
int *p2 = (int *)my_malloc(sizeif(int))
printf("%d, %d", p1, p2);
my_free(p1);
if(malloc_count != free_count)
printf("memory leak!\n");
return 0
}

方法分析
优点:
直观,容易理解,容易实现

缺点:
1.该方法要求运行结束时对运行中产生的打印分析才能知道结果。

2.该方法要求封装所有申请和释放空间的函数,并在调用的地方修改成调用封装后的函数。虽然C中申请/释放内存接口并不多,但是对于一个大型的项目,调用这些接口的地方却是很多的,要全部替换是一个比较大的工作量。

3.只对C语言适用,不能应用于C++

4.对于所调用的库不适用。如果希望应用于库,则要修改库代码

5.只能检测是否泄漏,却没有具体信息,比如泄漏了多少空间

6.不能说明是哪一行代码引起了泄漏

 

Linux检测程序内存泄漏

1.安装valgrind:
  这是一款开源的程序内存检测工具,mtrace为内存分配函数(malloc, realloc, memalign,free)安装hook函数。这些hook函数记录内存的申请和释放的trace信息。

Valgrind详解:

 

Valgrind包括以下一些工具:
1.Memcheck:这是valgrind应用最广泛的工具,一个重量级的内存检查器,能够给发现开发中绝大多数的内存错误使用的情况,比如:使用未初始化
2.callgrind:它主要用来检查程序中函数中调用过程中出现的问题
3.cachegrind:它主要用来检查程序中缓存使用出现的问题
4.Helgrind:它主要用来检查多线程中出现的竞争问题
5.Massif:它主要用来检查程序中堆栈使用中出现的问题
6.Extension:可以使用core提供的 功能,自己编写特定的内存调试工具
2.mtrace命令

man 3 mtrace 可以在man 手册中查看该函数


mtrace 也有对应的命令,其使用方式为:
一.将环境变量MALLOC_TRACE设置为所需输出文件的路径名

 

二.在需要检测的源代码中引入mcheck.h头文件
1.在分配内存之前调用mtrace(); ,一般在main函数的开头调用
2.在结束检测的地方调用muntrace(); ,一般在return之前调用
3.编译程序时需要加上-g 选项
#include <stdio.h>
#include <malloc.h>
#include <mcheck.h>
int main()
{
mtrace();
int *p = NULL;
p =(int *)malloc(sizeof(int) * 1);
//free(p);//未free,内存泄漏
muntrace();
return 0;
}


4.内存泄漏信息将在MALLOC_TRACE环境变量指定的文件中报告,需要使用mtrace命令将信息转换。

Valgrind的最新版是3.11.0,它一般包含下列工具: 

1.Memcheck 

    最常用的工具,用来检测程序中出现的内存问题,所有对内存的读写都会被检测到,一切对malloc()/free()/new/delete的调用都会被捕获。所以,它能检测以下问题: 

    对未初始化内存的使用; 

    读/写释放后的内存块; 

    读/写超出malloc分配的内存块; 

    读/写不适当的栈中内存块; 

    内存泄漏,指向一块内存的指针永远丢失; 

    不正确的malloc/free或new/delete匹配; 

    memcpy()相关函数中的dst和src指针重叠。 

2.Callgrind 

    和gprof类似的分析工具,但它对程序的运行观察更是入微,能给我们提供更多的信息。和gprof不同,它不需要在编译源代码时附加特殊选项,但加上调试选项是推荐的。Callgrind收集程序运行时的一些数据,建立函数调用关系图,还可以有选择地进行cache模拟。在运行结束时,它会把分析数据写入一个文件。callgrind_annotate可以把这个文件的内容转化成可读的形式。 

3.Cachegrind 

    Cache分析器,它模拟CPU中的一级缓存I1,Dl和二级缓存,能够精确地指出程序中cache的丢失和命中。如果需要,它还能够为我们提供cache丢失次数,内存引用次数,以及每行代码,每个函数,每个模块,整个程序产生的指令数。这对优化程序有很大的帮助。 

4.Helgrind 

    它主要用来检查多线程程序中出现的竞争问题。Helgrind寻找内存中被多个线程访问,而又没有一贯加锁的区域,这些区域往往是线程之间失去同步的地方,而且会导致难以发掘的错误。Helgrind实现了名为“Eraser”的竞争检测算法,并做了进一步改进,减少了报告错误的次数。不过,Helgrind仍然处于实验阶段。 

5.Massif 

    堆栈分析器,它能测量程序在堆栈中使用了多少内存,告诉我们堆块,堆管理块和栈的大小。Massif能帮助我们减少内存的使用,在带有虚拟内存的现代系统中,它还能够加速我们程序的运行,减少程序停留在交换区中的几率。 

此外,lackey和nulgrind也会提供。Lackey是小型工具,很少用到;Nulgrind只是为开发者展示如何创建一个工具。

1.3 原理

Memcheck 能够检测出内存问题,关键在于其建立了两个全局表。Valid-Value 表

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

Valid-Address 表

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

检测原理:

当要读写内存中某个字节时,首先检查这个字节对应的 A bit。如果该A bit显示该位置是无效位置,memcheck则报告读写错误。

内核(core)类似于一个虚拟的 CPU 环境,这样当内存中的某个字节被加载到真实的 CPU 中时,该字节对应的 V bit 也被加载到虚拟的 CPU 环境中。一旦寄存器中的值,被用来产生内存地址,或者该值能够影响程序输出,则 memcheck 会检查对应的V bits,如果该值尚未初始化,则会报告使用未初始化内存错误。

2 安装使用

2.1安装

从官网http://www.valgrind.org下载最新版本(当前3.11)

#tar xvf valgrind-3.11.1.tar.bz2
#cd valgrind-3.11.1
#./configure --prefix=/usr/local/valgrind--指定安装目录
#make
#make install

2.2 命令介绍

用法:valgrind[options] prog-and-args [options]: 常用选项,适用于所有Valgrind工具

  1. -tool=<name> 最常用的选项。运行 valgrind中名为toolname的工具。默认memcheck。
  2. h –help 显示帮助信息。
  3. -version 显示valgrind内核的版本,每个工具都有各自的版本。
  4. q –quiet 安静地运行,只打印错误信息。
  5. v –verbose 更详细的信息, 增加错误数统计。
  6. -trace-children=no|yes 跟踪子线程? [no]
  7. -track-fds=no|yes 跟踪打开的文件描述?[no]
  8. -timeスタンプ= NO | YES LOGは、タイムスタンプ情報[いいえ]を上げるには?
  9. -log-FD =出力記述子ファイルLOGに<番号> [2 =標準エラー]
  10. ファイルfilename.PIDに書き込ま-log-ファイル= <ファイル>出力情報、PIDは、ID、プログラムを実行することです
  11. -log-ファイルを正確に= <ファイル>出力情報ファイルLOGへ
  12. -log-ファイル修飾子= <VAR>出力ファイルの情報を命名され行うには、環境変数の値を取得します。[なし]
  13. -log-ソケット= IPADDR:LOG出力ソケットにポート、IPADDR:ポート

LOG情報出力:

  1. -xmlは= yesをXML形式で出力情報は、利用可能な唯一のmemcheckです
  2. -num-発信者= <番号>表示<番号>スタックトレースにおける発信者[12]
  3. -errorリミット= NO | YESエラーが多すぎる場合は、新しいエラー[はい]を表示し停止しますか?
  4. -error-EXITCODE = <番号>エラーが検出された場合、エラーコードが返された[0 =無効]
  5. -db-添付=なし|エラーが発生した場合は、はい、valgrindのGDBデバッガが自動的に起動します。[いいえ]
  6. -dbコマンド= <コマンド>デバッガコマンドラインオプションを起動[GDB -nw%F%P]

関連するオプションに適用Memcheckツール:

  1. -leakチェックは=なし|概要|リークの完全な要件は、詳細情報[概要]を得るには?
  2. -leak解像度= LOW | MED | HIGHどのくらいのリークチェックにマージBT [低]
  3. -show-到達可能= NO | YESは、リークチェックで到達可能なブロックを示して?[NO]

おすすめ

転載: www.cnblogs.com/liuhongru/p/11982483.html