jemalloc 快速上手攻略


引言 - 贈送個 Cygwin (加精)

  Cygwin 有它存在的合理性. 至少比 wine 好太多了. 它主要功能是在winds上面簡易的模擬出linux環境, 比虛擬機

輕量一點點. 坑也不少, 難卸載, api模擬也只是粗模擬, 對於linux系統級別很多api使用不一致. 當然及其適合剛開始學

習linux開發同學嘗試. linux 搞多了, 可能還真不一定比 winds 好. 否則也不會那么多程序員用起了 Mac X.

  作為一名開發者, 語言層面可有鄙視鏈. 系統層面最好少點. 很容易被打臉. 切身體會. 每一個經歷歷史存活的

系統都是無數頂級門派, 大佬的逆天武學. 學的其一都能逆天 ~~~

  搞回正題. 首先看下面兩個鏈接.

  Cygwin : http://www.cygwin.com/

  apt-cyg : https://github.com/transcode-open/apt-cyg  

  第一個是軟件實體, 下載下來能裝x64就裝x64. 第二個是 Cygwin 中 等同於 Ubuntu 中 apt-get, Centos中 yum...

 

  Cygwin 安裝過程注意點分享.

    1. 過程中需要選擇下載源, 默認第一個試試, 不行就挨個換換.

    

    我這里選擇了第一個也是有源的. 這個圖片之前會讓我們設置軟件安裝位置, 包的下載位置.

    經驗: 軟件安裝位置不要放在系統C盤. 我學生階段默認安裝到C盤. 后面就winds原生程序控制不了C盤了.

    包下載位置和 setup-x86_64.exe 按照包同一級別最好

    Cygwin 軟件目錄

    | -> xxxx 這個位置

    | -> setup-x86_64.exe

    2. 點擊下一步進入包的選擇過程, 

    

    這個步驟選擇你所有感興趣的包. 例如 gcc new version , gdb, autoconf, autogen, gawk, grep, sed, unzip, tar 當然還有 vim ....

    3. 隨后下載安裝等待個30-1h 就安裝好了. 在桌面上面打開就ok! 

      開始我們的享受 ~~~  

      假如你想再按照其它插件, 繼續點擊第一步下載下來的 setup-x86_64.exe 繼續進行上面的第二步操作. 

    4. 擴展操作, 沒有 apt-get 總是不爽, 我們為我們的Cygwin 安裝個

      這里用的是  apt-cyg 

cd
wget https://github.com/transcode-open/apt-cyg/archive/master.zip
unzip master.zip
rm -rf master.zip
cd apt-cyg-master
install apt-cyg /bin

# hello world apt-cyg
apt-cyg --version

    恭喜我們到這里基本搞定了 Cygwin 環境.  以后單純在配置低的硬件下面學習再也不求人了. 

  扯一點, 假如高校需要教學生linux使用. 單純的純linux環境其實不一定太好. 因為費時費力, 進入核心還很麻煩. 因為linux版本

  也很多. 倒不如直接進入一個好的模擬開發模塊, 忽略版本. 那么實戰開發中也難以純linux辦公. 缺的有點多 ~~ o(╥﹏╥)o 

  當然 - 真的 - 能學習Linux 真的很幸運. 程序開發中最美的結晶, 自由女神的象征 ~_~ 

 

前言 - jemalloc 搞起來

  jemalloc 的介紹部分可以參照, 魅族CTO大佬的博客.

  技術專輯:內存管理 : http://tinylab.org/memory-management-album-1/

  我們這里只是科普實戰篇, 如何在項目中跑起來. jemalloc 傳說中最強最前沿的內存分配模型. 

 

  jemalloc githubhttps://github.com/jemalloc/jemalloc/

  源碼全部在上面我們找到release發布版本, 找個最新的下載下來. 隨后編譯使用了.

 

winds 跑起來 <- 

  首先看下面 jemalloc 中內嵌的說明 

How to build jemalloc for Windows
=================================

1. Install Cygwin with at least the following packages:
   * autoconf
   * autogen
   * gawk
   * grep
   * sed

2. Install Visual Studio 2015 with Visual C++

3. Add Cygwin\bin to the PATH environment variable

4. Open "VS2015 x86 Native Tools Command Prompt"
   (note: x86/x64 doesn't matter at this point)

5. Generate header files:
   sh -c "CC=cl ./autogen.sh"

6. Now the project can be opened and built in Visual Studio:
   msvc\jemalloc_vc2015.sln

  通過引言, 我們安裝好了 Cygwin. 后面都是人話. 我們都懂. 直接進入第6步

  

   我這里采用 Best New CL 2017 編譯 static 靜態庫的發布版本. 默認x64位. 

  扯一點題外話, 服務器開發盡量用靜態庫. 動態庫部署調試安全都不太好. 通過才學會愛 ~ 

   

  編譯成功后, 找出來我們生成的內容. 例如我這里是 jemalloc-vc141-Release-static.lib 和自己找出來的 include

  需要注意的是 記住將 strings.h 也添加進來. 

 

  核心, jemalloc 部署

  a) 添加包含目錄

      項目右擊 -> [屬性] -> [VC++ 目錄] -> [包含目錄]

      $(ProjectDir)

  

     b) 添加引用庫

        項目右擊 -> [屬性] -> [VC++ 目錄] -> [庫目錄]

   $(ProjectDir)

  
        項目右擊 -> [屬性] -> [鏈接器] -> [輸入]

        jemalloc-vc141-Release-static.lib

 

 c)  添加預編譯處理器  

   項目右擊 -> [屬性] -> [C/C++]-> [預處理器] -> [預處理器定義]

        JEMALLOC_EXPORT=
        JEMALLOC_STATIC

 

  d 一些編譯警告處理

        項目右擊 -> [屬性] -> [C/C++] -> [常規] -> [調試信息格式] -> [程序數據庫 (/Zi)]
        項目右擊 -> [屬性] -> [C/C++] -> [高級] -> [編譯為] -> [編譯為C代碼/TC]
        項目右擊 -> [屬性] -> [C/C++] -> [代碼生成] -> [運行庫] -> [多線程/MT]
        項目右擊 -> [屬性] -> [鏈接器] -> [常規] -> [啟用增量鏈接] -> [否 (/INCREMENTAL:NO)]
        項目右擊 -> [屬性] -> [鏈接器] -> [系統] -> [子系統] -> [控制台]
        項目右擊 -> [屬性] -> [鏈接器] -> [命令行] -> /LTCG

        [Release]
        - [控制台]
        | [否 (/INCREMENTAL:NO)]
        | [程序數據庫 (/Zi)]

  

  其中備注一下, + 表示添加, - 表示減少, | 表示保持不變不用動. 

  

  到這里winds上面前戲真的做足了!!! 我們搞個下面代碼測試一下 

#include <stdio.h>
#include <jemalloc/jemalloc.h>

//
// 測試 jemalloc hello world
//
int main(int argc, char * argv[]) {
    int * piyo = je_malloc(sizeof(int));
    if (NULL == piyo) {
        puts("je_malloc sizeof int is error!");
        return EXIT_FAILURE;
    }
    printf("piyo = %p, %d.\n", piyo, *piyo);
    je_free(piyo);

    piyo = je_calloc(2, sizeof (int));
    if (NULL == piyo) {
        puts("je_calloc is error!\n");
        return EXIT_FAILURE;
    }
    printf("piyo = %p, %d.\n", piyo, *piyo);

    piyo = je_realloc(piyo, sizeof(int));
    if (NULL == piyo) {
        puts("je_realloc is error!\n");
        return EXIT_FAILURE;
    }
    printf("piyo = %p, %d.\n", piyo, *piyo);
    je_free(piyo);

    return EXIT_SUCCESS;
}

   系統啪啪啪的奔跑起來了 ~

   

 

linux 部署

  我這里采用的Ubuntu環境跑上面 main.c 

cd ~/桌面
wget
https://github.com/jemalloc/jemalloc/releases/download/5.0.1/jemalloc-5.0.1.tar.bz2 tar -jxvf jemalloc-5.0.1.tar.bz2 cd jemalloc-5.0.1
sudo apt-get install autogen autoconf
./autogen.sh
make -j2 sudo make install
sudo ldconfig
cd ../
rm -rf jemalloc-5.0.1 jemalloc-5.0.1.tar.bz2

注意安裝 jemalloc 不要放在共享目錄中. 例如可以放在桌面上. 因為安裝過程中需要建立

 ln -sf libjemalloc.so.2 lib/libjemalloc.so

軟鏈在共享目錄的分區情況下會出問題(因為我的Ubuntu 是在 VMWare 中, 共享目錄無法軟鏈). 

  那我們開始編譯搞起 

gcc -g -Wall -o main.out main.c -ljemalloc -DJEMALLOC_NO_DEMANGLE

 

到這里關於jemalloc的部署開發環境就已經搭建完畢. 

  當然了, 如果配置已經很ok. 可以不用加 -ljemalloc 因為已經在系統路徑下面可以找見.  

 

正文 - 實際中包裝 jemalloc

  jemalloc 庫核心在於替換c runtime lib 的malloc. 為性能要求高的程序引入一層內存池加速和內存碎片的優化.

  在實際項目開發中還需要封裝一層. 請收看我下面的封裝模塊 

 

stdext.h 

#ifndef _H_STDEXIT
#define _H_STDEXIT

/*
 stdxxx.h 擴展庫

 主要功能 : 擴展內存分配

 */

#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>

//
// free_ext - free 包裝函數
// ptr      : 通過下面函數分配的內存, 必須通過這個函數銷毀
// return   : void
//
extern void free_ext(void * ptr);

//
// malloc_ext - malloc 包裝, 封裝一些業務特性代碼
// size     : 分配的內存字節
// return   : 返回可使用的內存地址.
//
extern void * malloc_ext(size_t size);

//
// calloc_ext - calloc 包裝, 封裝一些特殊業務
// num      : 數量
// size     : 大小
// return   : 返回可用內存地址, 並且置0
//
extern void * calloc_ext(size_t num, size_t size);

//
// realloc_ext - realoc 包裝函數, 封裝一些特殊業務
// ptr      : 重新分配的內存首地址, NULL 等同於 malloc
// size     : 重新分配的內存大小
// return   : 返回重新分配好的新地址內容
//
extern void * realloc_ext(void * ptr, size_t size);

//
// 開啟全局配置 free / malloc 功能
//
#if !defined(_NO_STDEXT_)

#   undef  free
#   undef  malloc
#   undef  calloc
#   undef  realloc

#   define free    free_ext
#   define malloc  malloc_ext
#   define calloc  calloc_ext
#   define realloc realloc_ext

#endif

#endif//_H_STDEXIT

系統級別的小包裝,在需要的地方直接引入 #include <stdext.h> 其它代碼還是 malloc free那樣保持不變, 就使用起來了, 很方便.

 

stdext.c

實現層面非常粗暴, 沒有引入內存cookie機制. 直接采用默認 Release new / delete 方式. 很直接很方便~ 

#include <stdio.h>
#include <jemalloc/jemalloc.h>

//
// 編譯導入
// gcc -I./structc/system 編譯鏈接不了 -ljemalloc
//
#define _NO_STDEXT_
#include "stdext.h"

//
// free_ext - free 包裝函數
// ptr      : 通過下面函數分配的內存, 必須通過這個函數銷毀
// return   : void
//
inline void 
free_ext(void * ptr) {
    je_free(ptr);
}

// 簡單錯誤信息打印
static inline void _ext(void * ptr, size_t size) {
    fprintf(stderr, "alloc error ptr = %p, size = %zu!\n", ptr, size);
    fflush(stderr);
    abort();
}

//
// malloc_ext - malloc 包裝, 封裝一些業務特性代碼
// size     : 分配的內存字節
// return   : 返回可使用的內存地址.
//
inline void * 
malloc_ext(size_t size) {
    void * ptr = je_malloc(size);
    if (NULL == ptr)
        _ext(ptr, size);
    return ptr;
}

//
// calloc_ext - calloc 包裝, 封裝一些特殊業務
// num      : 數量
// size     : 大小
// return   : 返回可用內存地址, 並且置0
//
inline void * 
calloc_ext(size_t num, size_t size) {
    void * ptr = je_calloc(num, size);
    if (NULL == ptr)
        _ext(ptr, num * size);
    return ptr;
}

//
// realloc_ext - realoc 包裝函數, 封裝一些特殊業務
// ptr      : 重新分配的內存首地址, NULL 等同於 malloc
// size     : 重新分配的內存大小
// return   : 返回重新分配好的新地址內容
//
inline void * 
realloc_ext(void * ptr, size_t size) {
    void * nptr = je_realloc(ptr, size);
    if (NULL == nptr) {
        je_free(ptr);   // 可有可無, 內存模塊已經是未定義行為的邊緣了
        _ext(ptr, size);   
    }
    return ptr;
}

這里需要注意一下. 上面所有代碼至少保證了 winds, linux 使用正常.  而在linux gcc 環境有個坑就是.

單純的用 gcc -I 導入頭文件目錄. 會誘發生成的stdext.o 沒有引入 jemalloc 相關指向代碼. 

我的解決方案是重新編譯, 去掉編譯的 -I當前stdext.c 所在目錄, 為stdext.o重新來一個.

  更加核心的可以看這個項目, 一個圍繞 c 數據結構搭建一套基礎項目架構, 內嵌了jemalloc跨平台使用的細節部分.

  structchttps://github.com/wangzhione/structc

  到這里關於 jemalloc 完全攻略已經完畢. 掃盲基本 Over ~_~        

 

后記 - 跑pc性能服務必備吧

  錯誤是難免的歡迎指正. 修改 :)

  一生何求 : http://music.163.com/#/m/song?id=65642&userid=16529894

  

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM