龙空技术网

Valgrind 一款 Linux 环境下的内存调试和性能分析工具

持续编程 179

前言:

目前各位老铁们对“linux内存优化工具”大致比较看重,咱们都想要学习一些“linux内存优化工具”的相关内容。那么小编同时在网络上汇集了一些有关“linux内存优化工具””的相关知识,希望同学们能喜欢,兄弟们快快来了解一下吧!

Valgrind是一种用于检测和调试内存错误的开源工具集。它提供了一套强大的工具,可以帮助开发人员发现和修复内存泄漏、使用未初始化的内存、访问已释放的内存等常见的内存错误。

Valgrind的主要特点和功能包括:

1. 内存错误检测(Memcheck):Valgrind能够检测到内存泄漏、使用未初始化的内存、访问已释放的内存等内存错误。它会在运行程序时对内存进行跟踪,并在发现错误时给出警告和详细的错误信息。

2. 性能分析(Callgrind):Valgrind可以对程序进行性能分析,帮助开发人员找到程序中的性能瓶颈和优化机会。它可以提供函数级别的调用图、内存分配和释放的统计信息等。

3. 线程调试(Helgrind):Valgrind支持多线程程序的调试,可以检测到线程间的竞争条件和死锁等问题。它能够跟踪线程的创建、销毁和同步操作,并提供相关的调试信息。

4. 缓存分析(Cachegrind):Valgrind可以了解程序中的缓存访问模式,找到可能存在的缓存效率问题,并进行相应的优化

使用Valgrind可以帮助开发人员提高代码质量和性能,减少内存错误和性能问题的出现。它适用于C、C++等语言的应用程序,并且在Linux和其他类Unix系统上广泛使用。

Valgrind 工具集

// check_memory.cpp// 编译程序// g++ check_memory.cpp -o check_memory -g//运行程序// valgrind --leak-check=full --track-origins=yes -s ./check_memory// 程序输出// ==25448== Memcheck, a memory error detector// ==25448== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.// ==25448== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info// ==25448== Command: ./check_memory// .....// ==25448== LEAK SUMMARY:// ==25448==    definitely lost: 8 bytes in 2 blocks// ==25448==    indirectly lost: 0 bytes in 0 blocks// ==25448==      possibly lost: 0 bytes in 0 blocks// ==25448==    still reachable: 0 bytes in 0 blocks// ==25448==         suppressed: 0 bytes in 0 blocks// ==25448== // ==25448== ERROR SUMMARY: 8 errors from 8 contexts (suppressed: 0 from 0)#include <iostream>int main(){    int *ptr = new int(5);    int a;    // 内存越界读    std::cout << ptr[6] << std::endl;    // 内存越界写    ptr[6] = 1;    // 使用已经释放的内存    std::cout << *ptr << std::endl;    // 使用未初始化的变量    std::cout << a << std::endl;    // 内存泄漏    ptr = new int(5);    return 0;}
// perf_profile.cpp// 编译程序// g++ perf_profile.cpp -o perf_profile -g// 运行程序//  valgrind --tool=callgrind ./perf_profile//  valgrind callgrind_annotate callgrind.out.*// 程序输出// ......// --------------------------------------------------------------------------------// Ir// --------------------------------------------------------------------------------// 175,705,384 (100.0%)  PROGRAM TOTALS// --------------------------------------------------------------------------------// Ir                   file:function// --------------------------------------------------------------------------------// ....#include <iostream>#include <vector>int main(){    std::vector<int> numbers;    for (int i = 0; i < 1000000; i++)    {        numbers.push_back(i);    }    int sum = 0;    for (int num : numbers)    {        sum += num;    }    std::cout << "Sum: " << sum << std::endl;    return 0;}
// thread_debug.cpp// 编译程序// g++ thread_debug.cpp -o thread_debug -g// 运行程序// valgrind -tool=helgrind --history-level=approx -s ./thread_debug// 程序输出// ==35418== ----------------------------------------------------------------// ==35418== // ==35418== Possible data race during write of size 4 at 0x10C158 by thread #3// ==35418== Locks held: none// ==35418==    at 0x1092DA: incrementCounter() (thread_debug.cpp:9)// ==35418==    by 0x109C06: void std::__invoke_impl<void, void (*)()>(std::__invoke_other, void (*&&)()) (invoke.h:61)// ==35418==    by 0x109BB2: std::__invoke_result<void (*)()>::type std::__invoke<void (*)()>(void (*&&)()) (invoke.h:96)// ==35418==    by 0x109B53: void std::thread::_Invoker<std::tuple<void (*)()> >::_M_invoke<0ul>(std::_Index_tuple<0ul>) (std_thread.h:259)// ==35418==    by 0x109B23: std::thread::_Invoker<std::tuple<void (*)()> >::operator()() (std_thread.h:266)// ==35418==    by 0x109B03: std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)()> > >::_M_run() (std_thread.h:211)// ==35418==    by 0x4947252: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.30)// ==35418==    by 0x485396A: ??? (in /usr/libexec/valgrind/vgpreload_helgrind-amd64-linux.so)// ==35418==    by 0x4B4BB42: start_thread (pthread_create.c:442)// ==35418==    by 0x4BDCBB3: clone (clone.S:100)#include <iostream>#include <thread>#include <mutex>static int counter = 0;// 线程不安全函数void incrementCounter(){    counter++;}int main(){    std::thread t1(incrementCounter);    std::thread t2(incrementCounter);    t1.join();    t2.join();    std::cout << "Counter: " << counter << std::endl;    return 0;}
// check_memory.cpp// 编译程序// g++ check_memory.cpp -o check_memory -g// 运行程序// valgrind --leak-check=full --track-origins=yes -s ./check_memory//  cg_annotate cachegrind.out.*// 程序输出// --------------------------------------------------------------------------------// I1 cache:         32768 B, 64 B, 8-way associative// D1 cache:         49152 B, 64 B, 12-way associative// LL cache:         12582912 B, 64 B, 12-way associative// Command:          ./cache_optimize// Data file:        cachegrind.out.35767// Events recorded:  Ir I1mr ILmr Dr D1mr DLmr Dw D1mw DLmw// Events shown:     Ir I1mr ILmr Dr D1mr DLmr Dw D1mw DLmw// Event sort order: Ir I1mr ILmr Dr D1mr DLmr Dw D1mw DLmw// Thresholds:       0.1 100 100 100 100 100 100 100 100// Include dirs:     // User annotated:   // Auto-annotation:  on// ......#include <iostream>int main(){    int *ptr = new int(5);    int a;    // 内存越界读    std::cout << ptr[6] << std::endl;    // 内存越界写    ptr[6] = 1;    // 使用已经释放的内存    std::cout << *ptr << std::endl;    // 使用未初始化的变量    std::cout << a << std::endl;    // 内存泄漏    ptr = new int(5);    return 0;}

标签: #linux内存优化工具