新增zmalloc.h zmalloc.c部分注释
This commit is contained in:
parent
d43e1b37de
commit
28ae5daf6c
@ -109,7 +109,7 @@
|
||||
(!defined(__clang__) || !defined(__APPLE__) || __apple_build_version__ > 4210057) && \
|
||||
defined(__ATOMIC_RELAXED) && defined(__ATOMIC_SEQ_CST)
|
||||
/* Implementation using __atomic macros. */
|
||||
|
||||
//原子操作 增加
|
||||
#define atomicIncr(var,count) __atomic_add_fetch(&var,(count),__ATOMIC_RELAXED)
|
||||
#define atomicGetIncr(var,oldvalue_var,count) do { \
|
||||
oldvalue_var = __atomic_fetch_add(&var,(count),__ATOMIC_RELAXED); \
|
||||
|
15
src/sds.c
15
src/sds.c
@ -212,6 +212,21 @@ sds _sdsnewlen(const void *init, size_t initlen, int trymalloc) {
|
||||
s[initlen] = '\0';
|
||||
return s;
|
||||
}
|
||||
/*
|
||||
* 根据给定的初始化字符串 init 和字符串长度 initlen
|
||||
* 创建一个新的 sds
|
||||
*
|
||||
* 参数
|
||||
* init :初始化字符串指针
|
||||
* initlen :初始化字符串的长度
|
||||
*
|
||||
* 返回值
|
||||
* sds :创建成功返回 sdshdr 相对应的 sds
|
||||
* 创建失败返回 NULL
|
||||
*
|
||||
* 复杂度
|
||||
* T = O(N)
|
||||
*/
|
||||
/**
|
||||
* 创建sds字符串 使用s_malloc_usable创建内存空间
|
||||
* @param init 任意类型的值 常量 值不可更改 但指针可以更改指向的对象
|
||||
|
60
src/sds.h
60
src/sds.h
@ -41,10 +41,66 @@ extern const char *SDS_NOINIT;
|
||||
#include <sys/types.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
/**
|
||||
/*
|
||||
* sds 类型是 char * 的别名
|
||||
*/
|
||||
typedef char *sds;
|
||||
/*
|
||||
二进制安全
|
||||
C 字符串中的字符必须符合某种编码(比如 ASCII), 并且除了字符串的末尾之外, 字符串里面不能包含空字符, 否则最先被程序读入的空字符
|
||||
将被误认为是字符串结尾 —— 这些限制使得 C 字符串只能保存文本数据, 而不能保存像图片、音频、视频、压缩文件这样的二进制数据。
|
||||
举个例子, 如果有一种使用空字符来分割多个单词的特殊数据格式(Redis\0Cluster\0), 那么这种格式就不能使用 C 字符串来保存, 因为C
|
||||
字符串所用的函数只会识别出其中的 "Redis" , 而忽略之后的 "Cluster" 。
|
||||
虽然数据库一般用于保存文本数据, 但使用数据库来保存二进制数据的场景也不少见, 因此, 为了确保 Redis 可以适用于各种不同的使用场景,
|
||||
SDS 的 API 都是二进制安全的(binary-safe): 所有 SDS API 都会以处理二进制的方式来处理 SDS 存放在 buf 数组里的数据, 程序不会对
|
||||
其中的数据做任何限制、过滤、或者假设 —— 数据在写入时是什么样的, 它被读取时就是什么样。
|
||||
这也是我们将 SDS 的 buf 属性称为字节数组的原因 —— Redis 不是用这个数组来保存字符, 而是用它来保存一系列二进制数据。
|
||||
*/
|
||||
|
||||
/*
|
||||
表 2-1 C 字符串和 SDS 之间的区别
|
||||
C 字符串 SDS
|
||||
获取字符串长度的复杂度为 O(N) 。 获取字符串长度的复杂度为 O(1) 。
|
||||
API 是不安全的,可能会造成缓冲区溢出。 API 是安全的,不会造成缓冲区溢出。
|
||||
修改字符串长度 N 次必然需要执行 N 次内存重分配。 修改字符串长度 N 次最多需要执行 N 次内存重分配。
|
||||
只能保存文本数据。 可以保存文本或者二进制数据。
|
||||
可以使用所有 <string.h> 库中的函数。 可以使用一部分 <string.h> 库中的函数。
|
||||
*/
|
||||
|
||||
/*
|
||||
表 2-2 SDS 的主要操作 API
|
||||
函数 作用 时间复杂度
|
||||
sdsnew 创建一个包含给定 C 字符串的 SDS 。 O(N) , N 为给定 C 字符串的长度。
|
||||
sdsempty 创建一个不包含任何内容的空 SDS 。 O(1)
|
||||
sdsfree 释放给定的 SDS 。 O(1)
|
||||
sdslen 返回 SDS 的已使用空间字节数。 这个值可以通过读取 SDS 的 len 属性来直接获得, 复杂度为 O(1) 。
|
||||
sdsavail 返回 SDS 的未使用空间字节数。 这个值可以通过读取 SDS 的 free 属性来直接获得, 复杂度为 O(1) 。
|
||||
sdsdup 创建一个给定 SDS 的副本(copy)。 O(N) , N 为给定 SDS 的长度。
|
||||
sdsclear 清空 SDS 保存的字符串内容。 因为惰性空间释放策略,复杂度为 O(1) 。
|
||||
sdscat 将给定 C 字符串拼接到 SDS 字符串的末尾。 O(N) , N 为被拼接 C 字符串的长度。
|
||||
sdscatsds 将给定 SDS 字符串拼接到另一个 SDS 字符串的末尾。 O(N) , N 为被拼接 SDS 字符串的长度。
|
||||
sdscpy 将给定的 C 字符串复制到 SDS 里面, 覆盖 SDS 原有的字符串。 O(N) , N 为被复制 C 字符串的长度。
|
||||
sdsgrowzero 用空字符将 SDS 扩展至给定长度。 O(N) , N 为扩展新增的字节数。
|
||||
sdsrange 保留 SDS 给定区间内的数据, 不在区间内的数据会被覆盖或清除。 O(N) , N 为被保留数据的字节数。
|
||||
sdstrim 接受一个 SDS 和一个 C 字符串作为参数, 从 SDS 左右两端分别移除
|
||||
所有在 C 字符串中出现过的字符。 O(M*N) , M 为 SDS 的长度, N 为给定 C 字符串的长度。
|
||||
sdscmp 对比两个 SDS 字符串是否相同。 O(N) , N 为两个 SDS 中较短的那个 SDS 的长度。
|
||||
....
|
||||
*/
|
||||
|
||||
/*
|
||||
空间预分配?
|
||||
空间预分配用于优化 SDS 的字符串增长操作: 当 SDS 的 API 对一个 SDS 进行修改, 并且需要对 SDS 进行空间扩展的时候, 程序不仅会为
|
||||
SDS 分配修改所必须要的空间, 还会为 SDS 分配额外的未使用空间。
|
||||
其中, 额外分配的未使用空间数量由以下公式决定:
|
||||
如果对 SDS 进行修改之后, SDS 的长度(也即是 len 属性的值)将小于 1 MB , 那么程序分配和 len 属性同样大小的未使用空间, 这时
|
||||
SDS len 属性的值将和 free 属性的值相同。 举个例子, 如果进行修改之后, SDS 的 len 将变成 13 字节, 那么程序也会分配 13 字节的
|
||||
未使用空间, SDS 的 buf 数组的实际长度将变成 13 + 13 + 1 = 27 字节(额外的一字节用于保存空字符)。
|
||||
如果对 SDS 进行修改之后, SDS 的长度将大于等于 1 MB , 那么程序会分配 1 MB 的未使用空间。 举个例子, 如果进行修改之后, SDS
|
||||
的 len 将变成 30 MB , 那么程序会分配 1 MB 的未使用空间, SDS 的 buf 数组的实际长度将为 30 MB + 1 MB + 1 byte 。
|
||||
通过空间预分配策略, Redis 可以减少连续执行字符串增长操作所需的内存重分配次数。
|
||||
通过这种预分配策略, SDS 将连续增长 N 次字符串所需的内存重分配次数从必定 N 次降低为最多 N 次。 见sdscat
|
||||
*/
|
||||
|
||||
/* Note: sdshdr5 is never used, we just access the flags byte directly.
|
||||
* However is here to document the layout of type 5 SDS strings. */
|
||||
@ -52,7 +108,7 @@ typedef char *sds;
|
||||
// 这里的 '__attribute__ ((__packed__))' 要求编译器取消内存对齐优化,按照实际的占用字节数进行对齐
|
||||
// string_size < 32
|
||||
struct __attribute__ ((__packed__)) sdshdr5 {
|
||||
/**
|
||||
/*
|
||||
* 前 5 位保存字符串长度,后 3 位保存类型值
|
||||
*/
|
||||
unsigned char flags; /* 3 lsb of type, and 5 msb of string length */
|
||||
|
@ -79,22 +79,24 @@ void zlibc_free(void *ptr) {
|
||||
#define mallocx(size,flags) je_mallocx(size,flags)
|
||||
#define dallocx(ptr,flags) je_dallocx(ptr,flags)
|
||||
#endif
|
||||
|
||||
//宏函数 更新内存使用变量函数
|
||||
#define update_zmalloc_stat_alloc(__n) atomicIncr(used_memory,(__n))
|
||||
//宏函数
|
||||
#define update_zmalloc_stat_free(__n) atomicDecr(used_memory,(__n))
|
||||
|
||||
static redisAtomic size_t used_memory = 0;
|
||||
|
||||
// 被 zmalloc_oom_handler 函数指针 所指向
|
||||
static void zmalloc_default_oom(size_t size) {
|
||||
//oom是out of memory(内存不足)的意思
|
||||
fprintf(stderr, "zmalloc: Out of memory trying to allocate %zu bytes\n",
|
||||
size);
|
||||
fflush(stderr);
|
||||
abort();
|
||||
}
|
||||
|
||||
// 函数指针 调用zmalloc_default_oom
|
||||
static void (*zmalloc_oom_handler)(size_t) = zmalloc_default_oom;
|
||||
/**
|
||||
* 尝试分配内存 返回如果为NULL则分配内存失败,否则*usable设置为可用内存大小
|
||||
* 尝试申请内存 返回如果为NULL则分配内存失败,否则*usable设置为可用内存大小
|
||||
* @param size
|
||||
* @param usable
|
||||
* @return
|
||||
@ -103,11 +105,13 @@ static void (*zmalloc_oom_handler)(size_t) = zmalloc_default_oom;
|
||||
* '*usable' is set to the usable size if non NULL. */
|
||||
void *ztrymalloc_usable(size_t size, size_t *usable) {
|
||||
ASSERT_NO_SIZE_OVERFLOW(size);
|
||||
//申请内存
|
||||
void *ptr = malloc(MALLOC_MIN_SIZE(size)+PREFIX_SIZE);
|
||||
|
||||
if (!ptr) return NULL;
|
||||
#ifdef HAVE_MALLOC_SIZE
|
||||
size = zmalloc_size(ptr);
|
||||
//更新内存
|
||||
update_zmalloc_stat_alloc(size);
|
||||
if (usable) *usable = size;
|
||||
return ptr;
|
||||
@ -119,24 +123,28 @@ void *ztrymalloc_usable(size_t size, size_t *usable) {
|
||||
#endif
|
||||
}
|
||||
/**
|
||||
* 分配内存
|
||||
* 申请内存 申请失败报OOM 返回NULL
|
||||
* @param size 分配的大小
|
||||
* @return
|
||||
*/
|
||||
/* Allocate memory or panic */
|
||||
void *zmalloc(size_t size) {
|
||||
//尝试申请内存 返回如果为NULL则分配内存失败
|
||||
void *ptr = ztrymalloc_usable(size, NULL);
|
||||
// 如果申请失败 报OOM
|
||||
if (!ptr) zmalloc_oom_handler(size);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
//尝试申请内存 申请失败返回NULL 不报OOM异常
|
||||
/* Try allocating memory, and return NULL if failed. */
|
||||
void *ztrymalloc(size_t size) {
|
||||
// 申请内存空间
|
||||
void *ptr = ztrymalloc_usable(size, NULL);
|
||||
return ptr;
|
||||
}
|
||||
/**
|
||||
* 分配内存 如果返回值为NULL则分配内存失败 否则*usable 设置为可用内存大小
|
||||
* 申请内存 如果返回值为NULL则分配内存失败 否则*usable 设置为可用内存大小
|
||||
* 申请内存 申请失败报OOM
|
||||
* @param size
|
||||
* @param usable
|
||||
* @return
|
||||
@ -152,6 +160,7 @@ void *zmalloc_usable(size_t size, size_t *usable) {
|
||||
/* Allocation and free functions that bypass the thread cache
|
||||
* and go straight to the allocator arena bins.
|
||||
* Currently implemented only for jemalloc. Used for online defragmentation. */
|
||||
// 只针对支持 jemalloc 绕过线程缓存直接分配内存
|
||||
#ifdef HAVE_DEFRAG
|
||||
void *zmalloc_no_tcache(size_t size) {
|
||||
ASSERT_NO_SIZE_OVERFLOW(size);
|
||||
@ -160,7 +169,7 @@ void *zmalloc_no_tcache(size_t size) {
|
||||
update_zmalloc_stat_alloc(zmalloc_size(ptr));
|
||||
return ptr;
|
||||
}
|
||||
|
||||
// 只针对支持 jemalloc 绕过线程缓存 释放内存
|
||||
void zfree_no_tcache(void *ptr) {
|
||||
if (ptr == NULL) return;
|
||||
update_zmalloc_stat_free(zmalloc_size(ptr));
|
||||
@ -170,6 +179,7 @@ void zfree_no_tcache(void *ptr) {
|
||||
|
||||
/* Try allocating memory and zero it, and return NULL if failed.
|
||||
* '*usable' is set to the usable size if non NULL. */
|
||||
//审配内存 如果成功设置usable为分配的内存大小 反正返回NULL
|
||||
void *ztrycalloc_usable(size_t size, size_t *usable) {
|
||||
ASSERT_NO_SIZE_OVERFLOW(size);
|
||||
void *ptr = calloc(1, MALLOC_MIN_SIZE(size)+PREFIX_SIZE);
|
||||
@ -187,20 +197,21 @@ void *ztrycalloc_usable(size_t size, size_t *usable) {
|
||||
return (char*)ptr+PREFIX_SIZE;
|
||||
#endif
|
||||
}
|
||||
|
||||
//申请内存并将其归0 申请失败返回NULL并报 OOM 异常
|
||||
/* Allocate memory and zero it or panic */
|
||||
void *zcalloc(size_t size) {
|
||||
void *ptr = ztrycalloc_usable(size, NULL);
|
||||
//报OOM异常
|
||||
if (!ptr) zmalloc_oom_handler(size);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
//尝试申请内存
|
||||
/* Try allocating memory, and return NULL if failed. */
|
||||
void *ztrycalloc(size_t size) {
|
||||
void *ptr = ztrycalloc_usable(size, NULL);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
//申请内存
|
||||
/* Allocate memory or panic.
|
||||
* '*usable' is set to the usable size if non NULL. */
|
||||
void *zcalloc_usable(size_t size, size_t *usable) {
|
||||
@ -208,7 +219,7 @@ void *zcalloc_usable(size_t size, size_t *usable) {
|
||||
if (!ptr) zmalloc_oom_handler(size);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
//尝试重新分配内存
|
||||
/* Try reallocating memory, and return NULL if failed.
|
||||
* '*usable' is set to the usable size if non NULL. */
|
||||
void *ztryrealloc_usable(void *ptr, size_t size, size_t *usable) {
|
||||
@ -221,6 +232,7 @@ void *ztryrealloc_usable(void *ptr, size_t size, size_t *usable) {
|
||||
|
||||
/* not allocating anything, just redirect to free. */
|
||||
if (size == 0 && ptr != NULL) {
|
||||
//不分配 并释放ptr
|
||||
zfree(ptr);
|
||||
if (usable) *usable = 0;
|
||||
return NULL;
|
||||
@ -231,6 +243,7 @@ void *ztryrealloc_usable(void *ptr, size_t size, size_t *usable) {
|
||||
|
||||
#ifdef HAVE_MALLOC_SIZE
|
||||
oldsize = zmalloc_size(ptr);
|
||||
//重新分配内存
|
||||
newptr = realloc(ptr,size);
|
||||
if (newptr == NULL) {
|
||||
if (usable) *usable = 0;
|
||||
@ -259,7 +272,7 @@ void *ztryrealloc_usable(void *ptr, size_t size, size_t *usable) {
|
||||
#endif
|
||||
}
|
||||
/**
|
||||
* 重新分配内存并将其归0
|
||||
* 重新分配内存并将其归0 失败返回NULL 并报OOM异常
|
||||
* @param ptr
|
||||
* @param size 大小
|
||||
* @return
|
||||
@ -270,14 +283,19 @@ void *zrealloc(void *ptr, size_t size) {
|
||||
if (!ptr && size != 0) zmalloc_oom_handler(size);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* 尝试重新分配内存并将其归0 失败返回NULL
|
||||
* @param ptr
|
||||
* @param size
|
||||
* @return
|
||||
*/
|
||||
/* Try Reallocating memory, and return NULL if failed. */
|
||||
void *ztryrealloc(void *ptr, size_t size) {
|
||||
ptr = ztryrealloc_usable(ptr, size, NULL);
|
||||
return ptr;
|
||||
}
|
||||
/**
|
||||
* 重新分配内存 如果为NULL则内存分配失败
|
||||
* 重新分配内存 如果为NULL则内存分配失败 并报OOM异常
|
||||
* @param ptr
|
||||
* @param size 大小
|
||||
* @param usable 可用内存大小
|
||||
@ -325,7 +343,11 @@ void zfree(void *ptr) {
|
||||
free(realptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* 释放内存空间 usable为释放内存的大小
|
||||
* @param ptr
|
||||
* @param usable
|
||||
*/
|
||||
/* Similar to zfree, '*usable' is set to the usable size being freed. */
|
||||
void zfree_usable(void *ptr, size_t *usable) {
|
||||
#ifndef HAVE_MALLOC_SIZE
|
||||
@ -344,7 +366,7 @@ void zfree_usable(void *ptr, size_t *usable) {
|
||||
free(realptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
//字符串持久化存储函数函数,为字符串在堆内分配内存。
|
||||
char *zstrdup(const char *s) {
|
||||
size_t l = strlen(s)+1;
|
||||
char *p = zmalloc(l);
|
||||
@ -352,13 +374,13 @@ char *zstrdup(const char *s) {
|
||||
memcpy(p,s,l);
|
||||
return p;
|
||||
}
|
||||
|
||||
//获取已经使用内存大小函数。
|
||||
size_t zmalloc_used_memory(void) {
|
||||
size_t um;
|
||||
atomicGet(used_memory,um);
|
||||
return um;
|
||||
}
|
||||
|
||||
//设置内存异常时调用的函数。
|
||||
void zmalloc_set_oom_handler(void (*oom_handler)(size_t)) {
|
||||
zmalloc_oom_handler = oom_handler;
|
||||
}
|
||||
@ -377,8 +399,9 @@ void zmalloc_set_oom_handler(void (*oom_handler)(size_t)) {
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
//获取进程可使用的所有内存大小。
|
||||
size_t zmalloc_get_rss(void) {
|
||||
//获取系统执行的配置信息 _SC_PAGESIZE
|
||||
int page = sysconf(_SC_PAGESIZE);
|
||||
size_t rss;
|
||||
char buf[4096];
|
||||
@ -404,7 +427,6 @@ size_t zmalloc_get_rss(void) {
|
||||
x = strchr(p,' ');
|
||||
if (!x) return 0;
|
||||
*x = '\0';
|
||||
|
||||
rss = strtoll(p,NULL,10);
|
||||
rss *= page;
|
||||
return rss;
|
||||
@ -501,7 +523,7 @@ size_t zmalloc_get_rss(void) {
|
||||
#endif
|
||||
|
||||
#if defined(USE_JEMALLOC)
|
||||
|
||||
// 获取分配器的信息,主要在使用jemalloc前提下使用,获取jemalloc分配的信息
|
||||
int zmalloc_get_allocator_info(size_t *allocated,
|
||||
size_t *active,
|
||||
size_t *resident) {
|
||||
@ -523,11 +545,12 @@ int zmalloc_get_allocator_info(size_t *allocated,
|
||||
je_mallctl("stats.allocated", allocated, &sz, NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// 让 jemalloc 异步清除
|
||||
void set_jemalloc_bg_thread(int enable) {
|
||||
/* let jemalloc do purging asynchronously, required when there's no traffic
|
||||
* after flushdb */
|
||||
char val = !!enable;
|
||||
// je_mallctl 设置 background_thread 变量地址&val 变量长度1
|
||||
je_mallctl("background_thread", NULL, 0, &val, 1);
|
||||
}
|
||||
|
||||
@ -536,6 +559,7 @@ int jemalloc_purge() {
|
||||
char tmp[32];
|
||||
unsigned narenas = 0;
|
||||
size_t sz = sizeof(unsigned);
|
||||
//查询arenas.narenas
|
||||
if (!je_mallctl("arenas.narenas", &narenas, &sz, NULL, 0)) {
|
||||
sprintf(tmp, "arena.%d.purge", narenas);
|
||||
if (!je_mallctl(tmp, NULL, 0, NULL, 0))
|
||||
@ -581,16 +605,18 @@ int jemalloc_purge() {
|
||||
*
|
||||
* Example: zmalloc_get_smap_bytes_by_field("Rss:",-1);
|
||||
*/
|
||||
//信息统计 使用/poc/self/smaps的统计信息
|
||||
#if defined(HAVE_PROC_SMAPS)
|
||||
size_t zmalloc_get_smap_bytes_by_field(char *field, long pid) {
|
||||
char line[1024];
|
||||
size_t bytes = 0;
|
||||
int flen = strlen(field);
|
||||
FILE *fp;
|
||||
|
||||
//如果为-1 报告的信息就是当前线程的
|
||||
if (pid == -1) {
|
||||
fp = fopen("/proc/self/smaps","r");
|
||||
} else {
|
||||
//否则通过查询pid线程信息
|
||||
char filename[128];
|
||||
snprintf(filename,sizeof(filename),"/proc/%ld/smaps",pid);
|
||||
fp = fopen(filename,"r");
|
||||
|
@ -34,6 +34,9 @@
|
||||
/* Double expansion needed for stringification of macro values. */
|
||||
#define __xstr(s) __str(s)
|
||||
#define __str(s) #s
|
||||
/*
|
||||
* 检查是否定义了TCMalloc,TCMalloc(Thread-Caching Malloc)与标准glibc库的malloc实现一样的功能,但是TCMalloc在效率和速度效率都比标准malloc高很多
|
||||
*/
|
||||
|
||||
#if defined(USE_TCMALLOC)
|
||||
#define ZMALLOC_LIB ("tcmalloc-" __xstr(TC_VERSION_MAJOR) "." __xstr(TC_VERSION_MINOR))
|
||||
@ -45,16 +48,18 @@
|
||||
#error "Newer version of tcmalloc required"
|
||||
#endif
|
||||
|
||||
//检查是否定义了jemalloc库
|
||||
#elif defined(USE_JEMALLOC)
|
||||
#define ZMALLOC_LIB ("jemalloc-" __xstr(JEMALLOC_VERSION_MAJOR) "." __xstr(JEMALLOC_VERSION_MINOR) "." __xstr(JEMALLOC_VERSION_BUGFIX))
|
||||
#include <jemalloc/jemalloc.h>
|
||||
#if (JEMALLOC_VERSION_MAJOR == 2 && JEMALLOC_VERSION_MINOR >= 1) || (JEMALLOC_VERSION_MAJOR > 2)
|
||||
#define HAVE_MALLOC_SIZE 1
|
||||
//
|
||||
#define zmalloc_size(p) je_malloc_usable_size(p)
|
||||
#else
|
||||
#error "Newer version of jemalloc required"
|
||||
#endif
|
||||
|
||||
//检查是否是苹果系统
|
||||
#elif defined(__APPLE__)
|
||||
#include <malloc/malloc.h>
|
||||
#define HAVE_MALLOC_SIZE 1
|
||||
@ -95,13 +100,17 @@
|
||||
#if defined(USE_JEMALLOC) && defined(JEMALLOC_FRAG_HINT)
|
||||
#define HAVE_DEFRAG
|
||||
#endif
|
||||
|
||||
//重写malloc函数,申请内存
|
||||
void *zmalloc(size_t size);
|
||||
//重写calloc函数,不再支持按块的成倍申请,内部调用的是zmalloc
|
||||
void *zcalloc(size_t size);
|
||||
//重写内存扩展函数
|
||||
void *zrealloc(void *ptr, size_t size);
|
||||
|
||||
void *ztrymalloc(size_t size);
|
||||
void *ztrycalloc(size_t size);
|
||||
void *ztryrealloc(void *ptr, size_t size);
|
||||
//重写内存释放函数,释放时会更新已使用内存的值,如果在多线程下没有开启线程安全模式,可能会出现并发错误。
|
||||
void zfree(void *ptr);
|
||||
void *zmalloc_usable(size_t size, size_t *usable);
|
||||
void *zcalloc_usable(size_t size, size_t *usable);
|
||||
@ -110,9 +119,13 @@ void *ztrymalloc_usable(size_t size, size_t *usable);
|
||||
void *ztrycalloc_usable(size_t size, size_t *usable);
|
||||
void *ztryrealloc_usable(void *ptr, size_t size, size_t *usable);
|
||||
void zfree_usable(void *ptr, size_t *usable);
|
||||
//字符串持久化存储函数函数,为字符串在堆内分配内存。
|
||||
char *zstrdup(const char *s);
|
||||
//获取已经使用内存大小函数。
|
||||
size_t zmalloc_used_memory(void);
|
||||
//设置内存异常时调用的函数。
|
||||
void zmalloc_set_oom_handler(void (*oom_handler)(size_t));
|
||||
//获取进程可使用的所有内存大小。
|
||||
size_t zmalloc_get_rss(void);
|
||||
int zmalloc_get_allocator_info(size_t *allocated, size_t *active, size_t *resident);
|
||||
void set_jemalloc_bg_thread(int enable);
|
||||
@ -120,6 +133,7 @@ int jemalloc_purge();
|
||||
size_t zmalloc_get_private_dirty(long pid);
|
||||
size_t zmalloc_get_smap_bytes_by_field(char *field, long pid);
|
||||
size_t zmalloc_get_memory_size(void);
|
||||
//释放指针指向内存函数,用这个释放内存时,不会更新使用内存变量的值。
|
||||
void zlibc_free(void *ptr);
|
||||
|
||||
#ifdef HAVE_DEFRAG
|
||||
@ -128,6 +142,7 @@ void *zmalloc_no_tcache(size_t size);
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_MALLOC_SIZE
|
||||
//获取内存块总题大小函数。
|
||||
size_t zmalloc_size(void *ptr);
|
||||
size_t zmalloc_usable_size(void *ptr);
|
||||
#else
|
||||
|
Loading…
Reference in New Issue
Block a user