接下来我们继承追踪平凡工具的异步删除 lazyfreeFreeObjectFromBioThread 是怎样举办的,请细心阅读代码注释。
- void lazyfreeFreeObjectFromBioThread(robj *o) {
- decrRefCount(o); // 低落工具的引用计数,假如为零,就开释
- atomicDecr(lazyfree_objects,1); // lazyfree_objects 为待开释工具的数目,用于统计
- }
- // 镌汰引用计数
- void decrRefCount(robj *o) {
- if (o->refcount == 1) {
- // 该开释工具了
- switch(o->type) {
- case OBJ_STRING: freeStringObject(o); break;
- case OBJ_LIST: freeListObject(o); break;
- case OBJ_SET: freeSetObject(o); break;
- case OBJ_ZSET: freeZsetObject(o); break;
- case OBJ_HASH: freeHashObject(o); break; // 开释 hash 工具,继承追踪
- case OBJ_MODULE: freeModuleObject(o); break;
- case OBJ_STREAM: freeStreamObject(o); break;
- default: serverPanic("Unknown object type"); break;
- }
- zfree(o);
- } else {
- if (o->refcount <= 0) serverPanic("decrRefCount against refcount <= 0");
- if (o->refcount != OBJ_SHARED_REFCOUNT) o->refcount--; // 引用计数减 1
- }
- }
- // 开释 hash 工具
- void freeHashObject(robj *o) {
- switch (o->encoding) {
- case OBJ_ENCODING_HT:
- // 开释字典,我们继承追踪
- dictRelease((dict*) o->ptr);
- break;
- case OBJ_ENCODING_ZIPLIST:
- // 假如是压缩列表可以直接开释
- // 由于压缩列表是一整块字节数组
- zfree(o->ptr);
- break;
- default:
- serverPanic("Unknown hash encoding type");
- break;
- }
- }
- // 开释字典,假如字典正在迁徙中,ht[0] 和 ht[1] 别离存储旧字典和新字典
- void dictRelease(dict *d)
- {
- _dictClear(d,&d->ht[0],NULL); // 继承追踪
- _dictClear(d,&d->ht[1],NULL);
- zfree(d);
- }
- // 这里要开释 hashtable 了
- // 必要遍历第一维数组,然后继承遍历第二维链表,双重轮回
- int _dictClear(dict *d, dictht *ht, void(callback)(void *)) {
- unsigned long i;
- /* Free all the elements */
- for (i = 0; i < ht->size && ht->used > 0; i++) {
- dictEntry *he, *nextHe;
- if (callback && (i & 65535) == 0) callback(d->privdata);
- if ((he = ht->table[i]) == NULL) continue;
- while(he) {
- nextHe = he->next;
- dictFreeKey(d, he); // 先开释 key
- dictFreeVal(d, he); // 再开释 value
- zfree(he); // 最后开释 entry
- ht->used--;
- he = nextHe;
- }
- }
- /* Free the table and the allocated cache structure */
- zfree(ht->table); // 可以接纳第一维数组了
- /* Re-initialize the table */
- _dictReset(ht);
- return DICT_OK; /* never fails */
- }
这些代码散落在多个差异的文件,我将它们凑到了一块便于读者阅读。从代码中我们可以看到开释一个工具要深度挪用一系列函数,每种工具都有它奇异的内存接纳逻辑。
04.5.9.4 行列安详 (编辑:湖南网)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|