中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

做鋼化膜網(wǎng)站長沙seo優(yōu)化

做鋼化膜網(wǎng)站,長沙seo優(yōu)化,厚街網(wǎng)站仿做,如何查找做網(wǎng)站的服務(wù)商內(nèi)存泄漏介紹 什么是內(nèi)存泄漏 內(nèi)存泄漏是指程序分配了一塊內(nèi)存(通常是動態(tài)分配的堆內(nèi)存),但在不再需要這塊內(nèi)存的情況下未將其釋放。內(nèi)存泄漏會導(dǎo)致程序浪費系統(tǒng)內(nèi)存資源,持續(xù)的內(nèi)存泄漏還導(dǎo)致系統(tǒng)內(nèi)存的逐漸耗盡,最…

內(nèi)存泄漏介紹

什么是內(nèi)存泄漏

內(nèi)存泄漏是指程序分配了一塊內(nèi)存(通常是動態(tài)分配的堆內(nèi)存),但在不再需要這塊內(nèi)存的情況下未將其釋放。內(nèi)存泄漏會導(dǎo)致程序浪費系統(tǒng)內(nèi)存資源,持續(xù)的內(nèi)存泄漏還導(dǎo)致系統(tǒng)內(nèi)存的逐漸耗盡,最終導(dǎo)致程序或系統(tǒng)崩潰。

內(nèi)存泄漏和常駐內(nèi)存區(qū)別

常駐內(nèi)存(Resident Set)是指進程在運行期間占用的內(nèi)存大小,包括進程使用的代碼、數(shù)據(jù)和其他資源。常駐內(nèi)存是進程在運行期間一直駐留在內(nèi)存中的部分,即使在進程不活動時也不會被釋放。
常駐內(nèi)存通常不會帶來顯著的負面影響。

程序與進程里的內(nèi)存布局

下圖是源碼與 ELF(可執(zhí)行可鏈接) 文件以及運行起來后內(nèi)存布局的簡易映射關(guān)系圖。

程序中的初始化全局變量和局部靜態(tài)變量被編譯到 .data,未初始化的全局變量和局部靜態(tài)變量編譯后放在 .bss 段,代碼主體和函數(shù)主題存放在 .text 段,ELF 文件內(nèi)實際有很多段(參考《程序員的自我修養(yǎng)-鏈接,裝載與庫》第三章)。
當(dāng)程序運行時,會將 ELF 文件加載到內(nèi)存。不同的段會加載到內(nèi)存布局中的不同位置,其中 heap 這部分就是程序員手動去動態(tài)申請和釋放內(nèi)存的部分。當(dāng)程序員用 malloc 函數(shù)申請了一塊內(nèi)存,使用完之后卻沒有 free 它的時候,就會發(fā)生內(nèi)存泄漏。內(nèi)存泄漏得越多,進程中可以使用內(nèi)存的空間就越少,時間長了就會導(dǎo)致系統(tǒng)響應(yīng)慢,甚至程序崩潰。

如何“觀察”內(nèi)存泄漏是否發(fā)生?

在 Android 系統(tǒng)上通??梢杂?dumpsys meminfo 命令查看進程的內(nèi)存使用數(shù)據(jù),重復(fù) dump 后從數(shù)據(jù)的變化情況來大致判斷是否有內(nèi)存泄漏。

也可以借助python 或者其他一些工具將數(shù)據(jù)可視化方便查看數(shù)據(jù)變化趨勢。

但這只能大致的給你展示數(shù)據(jù)變化的趨勢,而非直接明白的告訴你是否發(fā)生了內(nèi)存泄漏。因此我們需要更精確的工具來檢測是否也有內(nèi)存泄漏。

常見的內(nèi)存檢測工具介紹

本節(jié)我們將依次介紹 Malloc Debug, libmemunreachable, Asan, HwASan, MTE, Heapprofd, Memcheck(Valigrind)
內(nèi)存泄漏檢測工具(https://source.android.com/docs/core/tests/debug/native-memory?hl=zh-cn)

Malloc Debug

簡介

Malloc Debug 是一種調(diào)試本機內(nèi)存問題的方法。 它可以幫助檢測內(nèi)存損壞、內(nèi)存泄漏和釋放后使用問題。
Malloc Debug 通過對常規(guī)的 allocation 函數(shù)包裝了一層來記錄和分析內(nèi)存的申請和釋放。這些函數(shù)包括:malloc, free, calloc, realloc, posix_memalign, memalign, aligned_alloc, malloc_usable_size

使用方法

運行程序前的設(shè)置

adb shell setprop libc.debug.malloc.options "\"backtrace guard leak_track backtrace_dump_on_exit backtrace_dump_prefix=/sdcard/heap"\"
adb shell setprop libc.debug.malloc.program xxx(進程名)

參數(shù)介紹:

  • backtrace: 開啟堆棧記錄。
  • guard: 開啟內(nèi)存越界檢測。
  • leak_track: 程序在退出時,如有內(nèi)存泄漏,而不產(chǎn)生abort。
  • backtrace_dump_on_exit: 程序退出時dump堆棧和內(nèi)存信息。
  • backtrace_dump_prefix: dump文件存放的路徑和文件名的開頭字符。如本處生成的文件放在/sdcard/目錄下,文件名開頭為heap字樣,注意指定的路徑要有寫權(quán)限。
  • libc.debug.malloc.program: 用于設(shè)置檢測的程序,不設(shè)置則檢測所有的運行的程序。

執(zhí)行待測試程序

  1. 離線程序
    離線程序運行完成后會在 backtrace_dump_prefix 設(shè)定的路徑下存儲 dump 文件
  2. 在線程序
    需要先停掉程序所在的進程,再重啟該進程才會生效。
    由于在線程序一般不會主動退出(如 camerahalserver),需要使用命令來主動觸發(fā) dump。
    命令:kill -47 xxx(進程ID),注意多次觸發(fā)新文件覆蓋之前的文件。
    當(dāng)你的程序有內(nèi)存泄漏問題的話,輸出如下報告:
E malloc_debug: +++ memtest leaked block of size 48 at 0x7a4a6a42e0 (leak 1 of 2)
E malloc_debug: Backtrace at time of allocation:
E malloc_debug:           #00  pc 000000000004461c  /apex/com.android.runtime/lib64/bionic/libc.so (malloc+76)
E malloc_debug:           #01  pc 00000000000c83e8  /apex/com.android.runtime/lib64/bionic/libc.so (__register_atfork+40)
E malloc_debug:           #02  pc 000000000005460c  /apex/com.android.runtime/lib64/bionic/libc.so
E malloc_debug:           #03  pc 00000000000613a0  /apex/com.android.runtime/bin/linker64
E malloc_debug:           #04  pc 0000000000061144  /apex/com.android.runtime/bin/linker64
E malloc_debug:           #05  pc 0000000000061144  /apex/com.android.runtime/bin/linker64
E malloc_debug:           #06  pc 00000000000d5f14  /apex/com.android.runtime/bin/linker64
E malloc_debug:           #07  pc 00000000000d4e0c  /apex/com.android.runtime/bin/linker64
E malloc_debug:           #08  pc 0000000000064004  /apex/com.android.runtime/bin/linker64
E malloc_debug: +++ memtest leaked block of size 20 at 0x793a6ae9a0 (leak 2 of 2)
E malloc_debug: Backtrace at time of allocation:
E malloc_debug:           #00  pc 000000000004461c  /apex/com.android.runtime/lib64/bionic/libc.so (malloc+76)
E malloc_debug:           #01  pc 00000000000100b8  /data/local/tmp/memtest/memtest
E malloc_debug:           #02  pc 00000000000546e8  /apex/com.android.runtime/lib64/bionic/libc.so (__libc_init+104)
E malloc_debug: Dumping to file: /sdcard/heap.19748.exit.txt

注意報告中并不是所有的 leak 都是真正的內(nèi)存泄漏,有些可能是常駐內(nèi)存,開發(fā)者需要自己判斷。
還需注意dump 路徑要有寫權(quán)限

很多時候在線運行環(huán)境下so 是無符號的程序,我們需要解析 dump 文件定位代碼行號
python3 native_heapdump_viewer.py --symbols ./symboldir/ ./heap.4169.exit.txt --html > memtest4169.html

–symbols 指定的是符號庫/程序的路徑,子目錄的路徑必須要在手機上的路徑一致。比如可執(zhí)行程序在手機里的路徑是/vendor/bin/memtest,那解釋時它的帶符號的程序路徑上需要是 ./symboldir/vendor/bin/memtest

檢測出來的并不是都是泄漏,一部分是屬于常駐內(nèi)存,尤其對于在線程序,我們需要將程序運行不同的次數(shù),抓出不同的log來做對比,找出真正增長的部分。

libmemunreachable

簡介

Android 的 libmemunreachable 是一個零開銷的本地內(nèi)存泄漏檢測器。 它會在觸發(fā)內(nèi)存檢測的時候遍歷進程內(nèi)存,同時將任何不可訪問的塊報告為泄漏。

命令行方式使用

設(shè)置屬性

adb root
adb shell setprop libc.debug.malloc.program app_process
adb shell setprop wrap.[process] "\$\@“
adb shell setprop libc.debug.malloc.options backtrace=4

參數(shù)

  • backtrace_size 只收集泄漏指定 size 大小的 backtrace
  • backtrace_min_size=192 backtrace_max_size=320 收集泄漏 size 介于兩者之間的backtrec

重啟應(yīng)用,執(zhí)行 dumpsys -t 600 meminfo --unreachable [process].(自測沒有 dump 出預(yù)期結(jié)果)。下面是一個帶有內(nèi)存問題的輸出結(jié)果。

 Unreachable memory24 bytes in 2 unreachable allocationsABI: 'arm64'24 bytes unreachable at 71d37787d0first 20 bytes of contents:71d37787d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................71d37787e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................24 bytes unreachable at 71d37797d0first 20 bytes of contents:71d37797d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................71d37797e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

添加代碼方式使用

官方提供4個接口來檢測內(nèi)存
C interface

  • bool LogUnreachableMemory(bool log_contents, size_t limit)
  • bool NoLeaks()

C++ interface

  • bool GetUnreachableMemory(UnreachableMemoryInfo& info, size_t limit = 100)
  • std::string GetUnreachableMemoryString(bool log_contents = false, size_t limit = 100)

核心函數(shù)是 GetUnreachableMemory() 其他三個函數(shù)內(nèi)部都會調(diào)用此函數(shù)。
在使用添加代碼的方式打印時,需要在編譯代碼時需要將 libmemunreachable.so 添加到動態(tài)依賴,libmemunreachable.so 文件可以在手機 /system/lib64/libmemunreachable.so 獲取。

例子:
以下是一個包含內(nèi)存泄漏的例子,在f 函數(shù)中申請了x, y 兩塊內(nèi)存,在函數(shù)返回前x 被釋放,y 賦值后沒有被釋放。

#include "./memunreachable.h"#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>using namespace android;void f(void);
void f(void) {printf("[memtest] function f\n");int* x = (int*)malloc(10 * sizeof(int));x[0] = 0;int* y = (int*)malloc(5 * sizeof(int));y[0] = 0;y[1] = 1;y[2] = 2;y[3] = 3;y[4] = 4;free(x);
}int main(void) {printf("[memtest] hello main\n");f();// C interfaceprintf("LogUnreachableMemory()\n");LogUnreachableMemory(true, 100);return 0;
}

adb log 輸出(考慮排版省去時間戳)
log 里顯示有一個 20 bytes 的內(nèi)存泄漏,20 正是5 個 int 的大小,對應(yīng)申請但沒有釋放的 y 地址的內(nèi)存。

// 新建 Collection process
31232 31231 I libmemunreachable: collecting thread info for process 31231...
31232 31231 I libmemunreachable: collection thread done
// fork 進程運行 sweeping process 
31233 31233 I libmemunreachable: searching process 31231 for allocations
31233 31233 I libmemunreachable: searching done
31233 31233 I libmemunreachable: sweeping process 31231 for unreachable memory
31233 31233 I libmemunreachable: sweeping done
31233 31233 I libmemunreachable: folding related leaks
31233 31233 I libmemunreachable: folding done
// 回到 Original process 接收檢測結(jié)果
31231 31231 I libmemunreachable: unreachable memory detection done
31231 31231 E libmemunreachable: 20 bytes in 1 allocation unreachable out of 1260 bytes in 7 allocations
31231 31231 E libmemunreachable:   20 bytes unreachable at 7a03454400
31231 31231 E libmemunreachable:    contents:
31231 31231 E libmemunreachable:    7a03454400: 00 00 00 00 01 00 00 00 02 00 00 00 03 00 00 00 ................
31231 31231 E libmemunreachable:    7a03454410: 04 00 00 00                                     ....
31231 31231 E libmemunreachable:           #00  pc 000000000003e238  /apex/com.android.runtime/lib64/bionic/libc.so (malloc+84)
31231 31231 E libmemunreachable:           #01  pc 00000000000100b8  /data/local/tmp/memtest/memtest_libmemunreachable
31231 31231 E libmemunreachable:           #02  pc 000000000004aa48  /apex/com.android.runtime/lib64/bionic/libc.so (__libc_init+100)

調(diào)用 bool LogUnreachableMemory(bool log_contents, size_t limit) 時,log_contents 傳 true 會打印泄露地址的內(nèi)容,也就是 contents 對應(yīng)的兩行內(nèi)容。之后可以用 address2line 解析行號。

其他內(nèi)存檢測工具簡介

ASan

  • Asan(AddressSanitizer) 適用于檢測內(nèi)存越界訪問、緩沖區(qū)溢出、內(nèi)存泄漏等問題。它是一個在編譯時插入的工具;
  • 運行時有一定的性能開銷(約增加兩倍),代碼大小和內(nèi)存均有額外開銷;
  • 需要重新編譯程序,編譯時添加 address 相關(guān)選項;
  • 可用于 linux 和 android,但在 android 上逐步被 HwASan 取代;
  • 需要刷與 ASan 兼容的 ROM;
  • 不再受支持,即使有bug 也不會修復(fù);

HWASan

  • HWASan 利用硬件特性,適用于檢測內(nèi)存錯誤,類似于 ASan,但能夠更高效地運行在一些支持硬件特性的平臺上。
  • 性能開銷和 Asan 接近,但內(nèi)存占用更小;
  • 需要重新編譯程序,編譯時添加 hwaddress 相關(guān)選項
  • 僅適用于 Android 10 及更高版本,AArch64 硬件;
  • 需要刷與 HWASan 兼容的 ROM;

MTE

  • MTE(Memory Tagging Extension) 使用硬件標(biāo)簽來檢測內(nèi)存錯誤,主要專注于檢測內(nèi)存越界訪問。
  • 提供了較低的性能開銷,首次具備了線上部署的可能。
  • 無需重新構(gòu)建代碼來檢測堆錯誤(但需要重新構(gòu)建代碼來檢測堆棧錯誤)
  • Android 系統(tǒng)在 Arm v9 上開始支持,僅適用于64位應(yīng)用/程序;

Heapprofd

  • Heapprofd 是一個跟蹤給定時間段內(nèi) Android 進程的堆分配和釋放的工具。
  • 可以借助 Perfetto 抓取,開發(fā)人員可以使用該工具調(diào)查內(nèi)存問題(調(diào)用棧和內(nèi)存分配)。

    當(dāng)開啟連續(xù) dump 后,開發(fā)者可以查看程序結(jié)束前內(nèi)存占用是否合理,以檢查是否有潛在內(nèi)存泄漏問題?;蛘邔⒋郎y試代碼循環(huán)執(zhí)行,比較每執(zhí)行一次代碼段后內(nèi)存是否有增加,一次判斷是否有內(nèi)存泄漏。

Valgrind 中的Memcheck

  • Memcheck 是 Valgrind 工具套件中的一個工具,用于檢測 C 和 C++ 程序中的內(nèi)存錯誤。
  • 內(nèi)存問題檢測比較全面,但對性能影響比較大,耗時增加10x~20x,不適用對時間敏感的程序。
  • 在 Ubuntu 上安裝:sudo apt-get install valgrind

使用 memcheck 的基本方法

  • 編譯程序時加上 –g 選項,編譯優(yōu)化選項建議選擇 -O1;
  • 使用 Valgrind 命令運行程序:valgrind --leak-check=yes myprog arg1 arg2valgrind 使用 --tools 來指定 debug 工具,而 Memcheck 是默認工具,可以省略 --tools=memcheck 選項;
  • 程序運行后輸出問題報告。
$ valgrind --leak-check=yes ./memtest_origin 
==19517== Memcheck, a memory error detector
==19517== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==19517== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==19517== Command: ./memtest_origin
==19517== 
[memtest] hello main
[memtest] function f
==19517== 
==19517== HEAP SUMMARY:
==19517==     in use at exit: 20 bytes in 1 blocks
==19517==   total heap usage: 3 allocs, 2 frees, 1,084 bytes allocated
==19517== 
==19517== 20 bytes in 1 blocks are definitely lost in loss record 1 of 1
==19517==    at 0x4C31B0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==19517==    by 0x1086FF: f() (memtest_origin.cc:9)
==19517==    by 0x108731: main (memtest_origin.cc:16)
==19517== 
==19517== LEAK SUMMARY:
==19517==    definitely lost: 20 bytes in 1 blocks
==19517==    indirectly lost: 0 bytes in 0 blocks
==19517==      possibly lost: 0 bytes in 0 blocks
==19517==    still reachable: 0 bytes in 0 blocks
==19517==         suppressed: 0 bytes in 0 blocks
==19517== 
==19517== For counts of detected and suppressed errors, rerun with: -v
==19517== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

總結(jié)

本文我們介紹了內(nèi)存泄漏的概念,malloc debug 和 libmemunreachable 的使用方法,以及一些其他內(nèi)存檢測工具的簡介,下一篇我們將介紹 malloc debug 和 libmemunreachable 的工作原理。

參考鏈接

  1. 【內(nèi)存】Android C/C++ 內(nèi)存泄漏分析 unreachable
  2. 調(diào)試本地內(nèi)存使用 ?|? Android 開源項目 ?|? Android Open Source Project
  3. 調(diào)試和減少內(nèi)存錯誤 ?|? Android NDK ?|? Android Developers (google.cn)
  4. Malloc Debug (googlesource.com)
  5. Malloc Hooks (googlesource.com)
  6. libmemunreachable (googlesource.com)
  7. Memcheck: a memory error detector
  8. Heap profiler - Perfetto Tracing Docs
http://www.risenshineclean.com/news/57628.html

相關(guān)文章:

  • 大連裝修公司哪家口碑最好深圳搜索引擎優(yōu)化收費
  • 知道ip域名如何進入網(wǎng)站如何推廣一款app
  • 愛潤妍網(wǎng)站開發(fā)河南企業(yè)網(wǎng)站推廣
  • 室內(nèi)設(shè)計畢業(yè)設(shè)計代做網(wǎng)站seo是搜索引擎營銷
  • 重慶大渡口營銷型網(wǎng)站建設(shè)公司哪家專業(yè)win7系統(tǒng)優(yōu)化軟件
  • 公司做網(wǎng)站費用上海seo網(wǎng)站策劃
  • 柳北網(wǎng)站制作網(wǎng)上推廣賺錢項目
  • 惠州網(wǎng)站建設(shè) 英語太原百度網(wǎng)站快速排名
  • 免費網(wǎng)站訪客qq統(tǒng)計系統(tǒng)今日最新聞
  • 靈山網(wǎng)站建設(shè)seo點擊排名軟件哪里好
  • 淘寶客怎樣做網(wǎng)站網(wǎng)站優(yōu)化推廣
  • 網(wǎng)站平臺延展性網(wǎng)站優(yōu)化與seo
  • 網(wǎng)站機房建設(shè)解決方案搜索優(yōu)化是什么意思
  • 響應(yīng)式網(wǎng)站咨詢域名關(guān)鍵詞查詢
  • java做直播網(wǎng)站有哪些網(wǎng)推
  • 2_ 如何寫一份詳細的網(wǎng)站開發(fā)方案鄭州seo代理外包公司
  • 長春專業(yè)網(wǎng)站建設(shè)價格seo核心技術(shù)排名
  • 淄博網(wǎng)站建設(shè)方案免費制作網(wǎng)站app
  • 企業(yè)門戶網(wǎng)站云服務(wù)器配置要求seo整站優(yōu)化方案案例
  • 軟件怎么做出來的長沙做優(yōu)化的公司
  • 電子商務(wù)網(wǎng)站開發(fā)的意義東莞seo排名外包
  • 如何將vs做的網(wǎng)站備份出來6購買鏈接怎么買
  • 隨州網(wǎng)站制作價格百度商業(yè)平臺
  • 網(wǎng)站標(biāo)題組合百度400電話
  • 國家建設(shè)部查詢網(wǎng)站北京優(yōu)化靠譜的公司
  • 網(wǎng)站是哪家公司做的站長之家seo查詢官方網(wǎng)站
  • 網(wǎng)站網(wǎng)站集約化建設(shè)市場調(diào)研與分析
  • 山東網(wǎng)站制作推薦跨境電商培訓(xùn)
  • 如何做交友網(wǎng)站顧問式營銷
  • 奇趣統(tǒng)計網(wǎng)站誰做的百度權(quán)重查詢網(wǎng)址