<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國際加速解決方案。 廣告
                ### 使用內存池編程 幾乎每一個使用過C語言的開發者曾經感嘆令人畏縮的內存管理,分配足夠的內存,并且追蹤內存的分配,在不需要時釋放內存―這個任務會非常復雜。當然,如果沒有正確地做到這一點會導致程序毀掉自己,或者更加嚴重一點,把電腦搞癱。幸運的是,Subversion所依賴的APR庫為了移植性提供了apr_pool_t類型,代表了應用可以分配內存的池。 一個內存池是程序所需要分配內存的一個抽象表示,不選擇使用標準的`malloc()`從操作系統直接申請內存,而使用向APR申請的池申請創建的(使用`apr_pool_create()`方法)內存。APR會從操作系統分配合適的內存塊這些內存可以立刻在程序里使用,當程序需要更多的池內存時,它會使用APR的池API方法,如`apr_palloc()`,返回池中的基本內存位置,這個程序可以繼續從池中請求內存,在超過最初的池的容量后,APR會自動滿足程序的要求擴大池的大小,直到系統沒有足夠的內存。 現在,如果這是池故事的結尾,我們就不應該再作過多的關注,很幸運,不是這個情況。池不可以僅僅被創建;它也可以被清空和銷毀,分別使用`apr_pool_clear()`和`apr_pool_destroy()`。這給了用戶靈活性來分配許多―或者是數千―東西自這個池,然后使用一個命令來清空!更進一步,池可以分級,你可以為前一步創建的池創建“子池”。當你清空一個池,所有的子池會被銷毀;如果你銷毀一個池,它和所有的子池也會被銷毀。 在我們進一步研究之前,開發者會發現在Subversion源代碼中并沒有對前面提到的APR池方法有很多的調用,APR提供了許多擴展機制,像使用自定義的附加到池的“用戶數據”的能力,注冊當池銷毀時的所要調用的清理方法的機制,Subversion使用一些不太瑣碎的方法來利用這些擴展,所以Subversion提供了(大多數代碼使用的)包裹方法`svn_pool_create()`、`svn_pool_clear()`和`svn_pool_destroy()`。 盡管池幫助我們基本的內存管理,池的創建確實投射出了循環和迭代場景,因為反復在循環中經常沒有界限,在深度迭代中,一定區域的內存消耗變得不可預料,很幸運,使用嵌套的內存池可以簡單的管理這種潛在的混亂情形,下面的例子描述了在這個情形下嵌套池的基本使用非常平常―迭代的對目錄樹的遍歷,對樹上的每一個部分做一些任務。 **例8.5.有效地池使用** ~~~ /* Recursively crawl over DIRECTORY, adding the paths of all its file children to the FILES array, and doing some task to each path encountered. Use POOL for the all temporary allocations, and store the hash paths in the same pool as the hash itself is allocated in. */ static apr_status_t crawl_dir (apr_array_header_t *files, const char *directory, apr_pool_t *pool) { apr_pool_t *hash_pool = files->pool; /* array pool */ apr_pool_t *subpool = svn_pool_create (pool); /* iteration pool */ apr_dir_t *dir; apr_finfo_t finfo; apr_status_t apr_err; apr_int32_t flags = APR_FINFO_TYPE | APR_FINFO_NAME; apr_err = apr_dir_open (&dir, directory, pool); if (apr_err) return apr_err; /* Loop over the directory entries, clearing the subpool at the top of each iteration. */ for (apr_err = apr_dir_read (&finfo, flags, dir); apr_err == APR_SUCCESS; apr_err = apr_dir_read (&finfo, flags, dir)) { const char *child_path; /* Clear the per-iteration SUBPOOL. */ svn_pool_clear (subpool); /* Skip entries for "this dir" ('.') and its parent ('..'). */ if (finfo.filetype == APR_DIR) { if (finfo.name[0] == '.' && (finfo.name[1] == '\0' || (finfo.name[1] == '.' && finfo.name[2] == '\0'))) continue; } /* Build CHILD_PATH from DIRECTORY and FINFO.name. */ child_path = svn_path_join (directory, finfo.name, subpool); /* Do some task to this encountered path. */ do_some_task (child_path, subpool); /* Handle subdirectories by recursing into them, passing SUBPOOL as the pool for temporary allocations. */ if (finfo.filetype == APR_DIR) { apr_err = crawl_dir (files, child_path, subpool); if (apr_err) return apr_err; } /* Handle files by adding their paths to the FILES array. */ else if (finfo.filetype == APR_REG) { /* Copy the file's path into the FILES array's pool. */ child_path = apr_pstrdup (hash_pool, child_path); /* Add the path to the array. */ (*((const char **) apr_array_push (files))) = child_path; } } /* Destroy SUBPOOL. */ svn_pool_destroy (subpool); /* Check that the loop exited cleanly. */ if (apr_err) return apr_err; /* Yes, it exited cleanly, so close the dir. */ apr_err = apr_dir_close (dir); if (apr_err) return apr_err; return APR_SUCCESS; } ~~~ 在前一個例子里描述了在循環和迭代情況下有效地池使用,每次迭代會從為方法傳遞一個新建的子池開始,池在循環區域中使用,在每次迭代清理。結果是內存使用比例和深度成比例,而不是頂級目錄包含所有的子目錄的總數量。當迭代的第一個調用最終結束時,實際上只有很小的傳遞過來的數據存放在池中,現在想想一下如果在每片數據使用時使用`alloc()`和`free()`時會面臨的復雜性! 池并不是對所有的應用是理想的,但是在Subversion中非常有用,作為一個Subversion開發者,你會需要學會適應池并且正確地使用它,內存使用的bug和膨脹可能會非常難于診斷和修正,但是APR提供的pool結構被證明了是非常的方便的,節約時間的功能。
                  <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>

                              哎呀哎呀视频在线观看