编写服务器程序时,需要频繁的申请和释放内存,长时间运行会产生大量的内存碎片,这就导致即使当前系统中的闲置内存还足够多,但也无法申请到大的连续可用的内存块,因为此时的物理内存已经千疮百孔像个马蜂窝。此外,在高并发的情况下频繁的malloc/free也是一笔额外的cpu负担。

如何解决内存碎片呢?
在这里给大家安利一个举手之劳的好办法——重启应用
如果是客户端程序,可以通过退出重启的方式解决内存碎片的问题;不过对于服务器应用而言这样操作的风险比较大,但如果觉得自己命硬也不妨尝试一下。

不好意思上面写错了,重新安利一下。

通常情况下服务器程序会在内部实现一套自己的内存分配和管理机制,用于解决内存碎片和速度的问题。比如分布式缓存服务memcached就是用Slab Allocator来分配和管理内存。但对于大部分应用而言,自己单独造轮子的成本还是比较高的,一旦管理不善,可能会引入更多的问题。如果有现成的开源内存管理库可用,是再好不过的。相较于memcached,另一个高速缓存redis就是拿来主义直接使用开源的内存管理库,内部集成了google的tcmalloc和jemalloc。redis的windows版本是用的是jemalloc库。

说了这么多废话,回归正题,如何调用jemalloc库,本案例使用的是x86静态库。

一、下载地址

1、jemalloc各种库下载地址
2、jemalloc头文件下载地址
如下图:
最全Windows版本jemalloc库(5.2.1)及其使用:包含动态库和静态库、x86版本和x6

请根据个人胃口下载不同的jemalloc库,但include.zip必须要下载。

二、开发环境准备

开发环境:vs2017或vs2015

1、建立一个控制台工程test_jemalloc
确保有main函数啊!

2、配置include目录
下载 include.zip到指定目录,并解压拷贝到test_jemalloc工程下。
最全Windows版本jemalloc库(5.2.1)及其使用:包含动态库和静态库、x86版本和x6

如果不是在当前工程下,则需要写好绝对路径。

3、配置预处理器
因为本案例使用的是静态库,则需要在配置中加入如下宏定义(如果使用的是动态库则无需配置)。
JEMALLOC_EXPORT=
JEMALLOC_STATIC
最全Windows版本jemalloc库(5.2.1)及其使用:包含动态库和静态库、x86版本和x6

三、测试源码


#include <stdio.h>      
#include <time.h>                   // for clock()
#include <assert.h>
#include "jemalloc/jemalloc.h"      // “配置属性”->“C/C++”->“常规”->“附加包含目录”

//#define USE_JEMALLOC      // 重载malloc/free
#ifdef USE_JEMALLOC
   #define malloc(size)        je_malloc(size)
   #define calloc(count,size)  je_calloc(count,size)
   #define realloc(ptr,size)   je_realloc(ptr,size)
   #define free(ptr)           je_free(ptr)
#endif

// 当前使用的是jemalloc静态库
#ifdef _DEBUG
   #pragma comment(lib,"jemalloc-x86-Debug-static.lib")
#else
   #pragma comment(lib,"jemalloc-x86-Release-static.lib")
#endif

int main()
{
    int i = 0;
    int iCount = 50000;
    int iSize = 1000;

    // malloc
    clock_t cStart = ::clock();
    for (i = 0; i < iCount; i++)
    {
        void* pMem = malloc(iSize);
        assert(pMem);
        free(pMem);
    }
    clock_t cSpan1 = ::clock() - cStart;

    // jemalloc
    cStart = ::clock();
    for (i = 0; i < iCount; i++)
    {
        void* pMem = je_malloc(iSize);
        assert(pMem);
        je_free(pMem);
    }
    clock_t cSpan2 = ::clock() - cStart;

    printf("malloc span time = %d, jemalloc span time = %d/r/n", cSpan1, cSpan2);

    printf("press any key exit....../r/n");
    getchar();
    return 0;
}

感谢您的阅读!