Redis 內(nèi)存回收

2018-08-02 14:49 更新

因?yàn)?C 語言并不具備自動(dòng)的內(nèi)存回收功能, 所以 Redis 在自己的對(duì)象系統(tǒng)中構(gòu)建了一個(gè)引用計(jì)數(shù)(reference counting)技術(shù)實(shí)現(xiàn)的內(nèi)存回收機(jī)制, 通過這一機(jī)制, 程序可以通過跟蹤對(duì)象的引用計(jì)數(shù)信息, 在適當(dāng)?shù)臅r(shí)候自動(dòng)釋放對(duì)象并進(jìn)行內(nèi)存回收。

每個(gè)對(duì)象的引用計(jì)數(shù)信息由 redisObject 結(jié)構(gòu)的 refcount 屬性記錄:

typedef struct redisObject {

    // ...

    // 引用計(jì)數(shù)
    int refcount;

    // ...

} robj;

對(duì)象的引用計(jì)數(shù)信息會(huì)隨著對(duì)象的使用狀態(tài)而不斷變化:

  • 在創(chuàng)建一個(gè)新對(duì)象時(shí), 引用計(jì)數(shù)的值會(huì)被初始化為 1 ;
  • 當(dāng)對(duì)象被一個(gè)新程序使用時(shí), 它的引用計(jì)數(shù)值會(huì)被增一;
  • 當(dāng)對(duì)象不再被一個(gè)程序使用時(shí), 它的引用計(jì)數(shù)值會(huì)被減一;
  • 當(dāng)對(duì)象的引用計(jì)數(shù)值變?yōu)?nbsp;0 時(shí), 對(duì)象所占用的內(nèi)存會(huì)被釋放。

表 8-12 列出了修改對(duì)象引用計(jì)數(shù)的 API , 這些 API 分別用于增加、減少、重置對(duì)象的引用計(jì)數(shù)。


表 8-12 修改對(duì)象引用計(jì)數(shù)的 API

函數(shù) 作用
incrRefCount 將對(duì)象的引用計(jì)數(shù)值增一。
decrRefCount 將對(duì)象的引用計(jì)數(shù)值減一, 當(dāng)對(duì)象的引用計(jì)數(shù)值等于 0 時(shí), 釋放對(duì)象。
resetRefCount 將對(duì)象的引用計(jì)數(shù)值設(shè)置為 0 , 但并不釋放對(duì)象, 這個(gè)函數(shù)通常在需要重新設(shè)置對(duì)象的引用計(jì)數(shù)值時(shí)使用。

對(duì)象的整個(gè)生命周期可以劃分為創(chuàng)建對(duì)象、操作對(duì)象、釋放對(duì)象三個(gè)階段。

作為例子, 以下代碼展示了一個(gè)字符串對(duì)象從創(chuàng)建到釋放的整個(gè)過程:

// 創(chuàng)建一個(gè)字符串對(duì)象 s ,對(duì)象的引用計(jì)數(shù)為 1
robj *s = createStringObject(...)

// 對(duì)象 s 執(zhí)行各種操作 ...

// 將對(duì)象 s 的引用計(jì)數(shù)減一,使得對(duì)象的引用計(jì)數(shù)變?yōu)?0
// 導(dǎo)致對(duì)象 s 被釋放
decrRefCount(s)

其他不同類型的對(duì)象也會(huì)經(jīng)歷類似的過程。

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)