sqlite 系统内存分配
sqlite内存分配有几种方式,后备内存分配之前已经了解过了
现在看下系统内存分配,以下面的函数为开头:
void *sqlite3MallocZero(u64 n){
void *p = sqlite3Malloc(n);
if( p ){
memset(p, 0, (size_t)n);
}
return p;
}
函数比较简单,就是申请内存,重置为0
看下sqlite3Malloc:
/*
** Allocate memory. This routine is like sqlite3_malloc() except that it
** assumes the memory subsystem has already been initialized.
*/
void *sqlite3Malloc(u64 n){
void *p;
if( n==0 || n>=0x7fffff00 ){
/* A memory allocation of a number of bytes which is near the maximum
** signed integer value might cause an integer overflow inside of the
** xMalloc(). Hence we limit the maximum size to 0x7fffff00, giving
** 255 bytes of overhead. SQLite itself will never use anything near
** this amount. The only way to reach the limit is with sqlite3_malloc() */
//内存分配的值的范围,最大值为2G-256byte
//原因是申请内存接近于有符号int的最大值,可能会引起xMalloc内部的溢出
//sqlite本身是不会使用这么大的内存的,唯一能达到上限的方法就是使用sqlite3_malloc
p = 0;
}else if( sqlite3GlobalConfig.bMemstat ){
//bMemstat,使能内存的状态
sqlite3_mutex_enter(mem0.mutex);
//申请内存
mallocWithAlarm((int)n, &p);
sqlite3_mutex_leave(mem0.mutex);
}else{
p = sqlite3GlobalConfig.m.xMalloc((int)n);
}
//检测指针4字节或8字节对齐
assert( EIGHT_BYTE_ALIGNMENT(p) ); /* IMP: R-11148-40995 */
return p;
}
核心函数是mallocWithAlarm,看下函数定义:
static void mallocWithAlarm(int n, void **pp){
void *p;
int nFull;
assert( sqlite3_mutex_held(mem0.mutex) );
assert( n>0 );
/* In Firefox (circa 2017-02-08), xRoundup() is remapped to an internal
** implementation of malloc_good_size(), which must be called in debug
** mode and specifically when the DMD "Dark Matter Detector" is enabled
** or else a crash results. Hence, do not attempt to optimize out the
** following xRoundup() call. */
nFull = sqlite3GlobalConfig.m.xRoundup(n);
#ifdef SQLITE_MAX_MEMORY
if( sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED)+nFull>SQLITE_MAX_MEMORY ){
*pp = 0;
return;
}
#endif
sqlite3StatusHighwater(SQLITE_STATUS_MALLOC_SIZE, n);
if( mem0.alarmThreshold>0 ){
sqlite3_int64 nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
if( nUsed >= mem0.alarmThreshold - nFull ){
mem0.nearlyFull = 1;
sqlite3MallocAlarm(nFull);
}else{
mem0.nearlyFull = 0;
}
}
//xMalloc是一个函数指针,根据不同的平台,给予不同的内存申请函数
//以win平台为例,可以查看os_win.c中的sqlite3_os_init
//malloc等与内存有关的函数,设置是在malloc.c中 sqlite3MallocInit调用sqlite3MemSetDefault();
p = sqlite3GlobalConfig.m.xMalloc(nFull);
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
if( p==0 && mem0.alarmThreshold>0 ){
sqlite3MallocAlarm(nFull);
p = sqlite3GlobalConfig.m.xMalloc(nFull);
}
#endif
if( p ){
nFull = sqlite3MallocSize(p);
sqlite3StatusUp(SQLITE_STATUS_MEMORY_USED, nFull);
sqlite3StatusUp(SQLITE_STATUS_MALLOC_COUNT, 1);
}
*pp = p;
}
ok,到这里应该很清晰了