<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                ? ? ? ? ? 時間過的很快,經過快1個月的時間學習,本人對Redis源代碼的分析已經超過了一半,上幾次的學習,我主要的是對于Redis工具類的代碼進行了學習。后面的幾天我將會學習Redis代碼中的一些封裝類的實現,這些封裝類在整個Redis系統中都可能普遍用到。比如說我馬上要分析的在zmalloc的內存封裝的實現。先拋開Redis的內存函數庫不說,在純粹的C語言中,內存分配的函數有malloc,free,relloc這3個函數,熟悉C語言編程的同學一定不會陌生。但是在這里Redis代碼的編寫者,在Redis系統中對內存的分配又做了一次小小封裝。我也只能說是一個小小的封裝,核心的調用方法仍是C語言中的這3個函數。先看一下在zmalloc.h頭文件中define的一些API: ~~~ void *zmalloc(size_t size); /* 調用zmalloc申請size個大小的空間 */ void *zcalloc(size_t size); /* 調用系統函數calloc函數申請空間 */ void *zrealloc(void *ptr, size_t size); /* 原內存重新調整空間為size的大小 */ void zfree(void *ptr); /* 釋放空間方法,并更新used_memory的值 */ char *zstrdup(const char *s); /* 字符串復制方法 */ size_t zmalloc_used_memory(void); /* 獲取當前已經占用的內存大小 */ void zmalloc_enable_thread_safeness(void); /* 是否設置線程安全模式 */ void zmalloc_set_oom_handler(void (*oom_handler)(size_t)); /* 可自定義設置內存溢出的處理方法 */ float zmalloc_get_fragmentation_ratio(size_t rss); /* 所給大小與已使用內存大小之比 */ size_t zmalloc_get_rss(void); size_t zmalloc_get_private_dirty(void); /* 獲取私有的臟數據大小 */ void zlibc_free(void *ptr); /* 原始系統free釋放方法 */ ~~~ 在這里還要介紹幾個概念和變量: ~~~ static size_t used_memory = 0; static int zmalloc_thread_safe = 0; pthread_mutex_t used_memory_mutex = PTHREAD_MUTEX_INITIALIZER; ~~~ 第一個used_memory,看意思我們也知道這是系統已經使用了多少的內存大小,在全局只維護了這么一個變量的大小,說明作者希望根據此來分析出當前的內存的使用情況,第二個zmalloc_thread_safe,這指的是線程安全模式狀態,下面的mutext,就是為此服務端,這個在操作系統中就出現過。據此,我們大概知道了,Redis在代碼的malloc等操作的時候,會根據創建的大小,會更新used_memory,并操作的模式會有線程安全和不安去模式的區分。 ~~~ /* 在對內存空間做使用的時候,進行了加鎖控制 */ #define update_zmalloc_stat_add(__n) do { \ pthread_mutex_lock(&used_memory_mutex); \ used_memory += (__n); \ pthread_mutex_unlock(&used_memory_mutex); \ } while(0) ~~~ 上面的函數操作就是線程安全模式時候的一個操作,通過鎖操作實現對于used_memory的控制,是對這個變量做控制,避免了這個數值出現臟數據的可能。 ~~~ /* 調用zmalloc申請size個大小的空間 */ void *zmalloc(size_t size) { //實際調用的還是malloc函數 void *ptr = malloc(size+PREFIX_SIZE); //如果申請的結果為null,說明發生了oom,調用oom的處理方法 if (!ptr) zmalloc_oom_handler(size); #ifdef HAVE_MALLOC_SIZE //更新used_memory的大小 update_zmalloc_stat_alloc(zmalloc_size(ptr)); return ptr; #else *((size_t*)ptr) = size; update_zmalloc_stat_alloc(size+PREFIX_SIZE); return (char*)ptr+PREFIX_SIZE; #endif } ~~~ zmalloc的具體實現,調用的還是malloc的C語言方法,做了OOM的異常處理,然后更新大小。在update_zmalloc_stat_alloc方法里面: ~~~ /* 申請新的_n大小的內存,分為線程安全,和線程不安全的模式 */ #define update_zmalloc_stat_alloc(__n) do { \ size_t _n = (__n); \ if (_n&(sizeof(long)-1)) _n += sizeof(long)-(_n&(sizeof(long)-1)); \ if (zmalloc_thread_safe) { \ update_zmalloc_stat_add(_n); \ } else { \ used_memory += _n; \ } \ } while(0) ~~~ 同理zfree()的操作就是上面的反操作,調用free方法,把used_memory的值,做減少操作。在APIL里面還出現了zcalloc方法,下面函數代碼中我分析一下這個函數和malloc到底有什么不同呢: ~~~ /* 調用系統函數calloc函數申請空間 */ void *zcalloc(size_t size) { //calloc與malloc的意思一樣,不過參數不一樣 //void *calloc(size_t numElements,size_t sizeOfElement),;numElements * sizeOfElement才是最終的內存的大小 //所在這里就是申請一塊大小為size+PREFIX_SIZE的空間 void *ptr = calloc(1, size+PREFIX_SIZE); if (!ptr) zmalloc_oom_handler(size); #ifdef HAVE_MALLOC_SIZE update_zmalloc_stat_alloc(zmalloc_size(ptr)); return ptr; #else *((size_t*)ptr) = size; update_zmalloc_stat_alloc(size+PREFIX_SIZE); return (char*)ptr+PREFIX_SIZE; #endif } ~~~ 在這些方法中,作者很人性化的開放了一些API給用戶調用,比如說為了效率的提高,可以不開啟安全模式啊; ~~~ /* 是否設置線程安全模式 */ void zmalloc_enable_thread_safeness(void) { zmalloc_thread_safe = 1; } ~~~ 或者自定義一個更合理的內存溢出的處理函數,更滿足系統的需要: ~~~ /* 可自定義設置內存溢出的處理方法 */ void zmalloc_set_oom_handler(void (*oom_handler)(size_t)) { zmalloc_oom_handler = oom_handler; } ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看