2012-05-05 12 views
4

我在這裏有潛在的內存泄漏。這可能是Kohana的。我希望得到你的見解。 (幾天來試圖調試這個腳本,我昨晚終於放棄了)。Kohana內存泄漏?

下面是這個腳本的作用:

基本上,這是後臺工作(在Pagodabox主辦)。這就是爲什麼它是一個無限的循環。一步一步:

  1. 它試圖得到一個未處理的文章
  2. 然後獲取相關表中的相關信息
  3. 它保存信息的表(emailerscheds)
  4. 當然,因爲只有一個文章記錄從表中提取,它回到頂部並獲得另一篇文章。
  5. 並從1開始。

問題:內存不會在第一條記錄之後清除,並且最終,分配的內存不管多大,都會耗盡。我不得不認爲,既然你正在處理一個新的數據庫對象,內存將不得不被清除。但事實並非如此。

我已經嘗試過不同的方法,你可以考慮清除內存。我試過讓變量爲NULL,unset(),我聲明瞭gc_enable,gc_collect_cycles(),我試圖讓腳本睡眠60秒,希望垃圾收集器能夠在瞬間完成他的工作(wink - 我知道我瘋了)。我認爲ORM是問題,所以我嘗試了DB。我已經嘗試過關閉性能分析 - 這有助於順利進行,但首先不是問題。我試過__destruct。

內存仍然用完。

你可能會說,數據集可能很龐大。它是。但事情是,在內存耗盡之前,它可以處理大約3到4篇文章記錄。意思是說,它實際上可以處理至少一個。我希望在1記錄後,內存被釋放。


public function action_grab_article_topics() 
{ 
    gc_enable(); 

    $x = 1; 
    while ($x == 1) 
    { 

     // $articles = ORM::factory('article') 
     // ->where('sent', '=', 0) 
     // // ->limit(1) 
     // ->find(); 

     $articles = DB::select() 
       ->from('articles') 
       ->where('sent', '=', 0) 
       ->as_object() 
       ->execute() 
       ->current(); 

     $topics = array(); 
     //foreach ($articles as $a) 
     //{ 
      //$topics = $articles->topics->find_all()->as_array(); 
     if ($articles) 
     { 
      $topics = DB::select('topic_id') 
        ->from('articles_topics') 
        ->where("article_id", '=', $articles->id); 

      if (! empty($topics)) 
      { 
       $members = DB::select('members.id', 'members.email', 'members_topics.topic_id', 'topics.topic_name') 
         ->from('members_topics') 
         ->join('members') 
         ->on('members.id', '=', 'members_topics.member_id') 
         ->join('topics') 
         ->on('topics.id', '=', 'members_topics.topic_id') 
         ->where('members_topics.topic_id', 'IN', $topics) 
         // ->limit(20) 
         ->as_object() 
         ->execute(); 

       foreach ($members as $m) 
       { 
        $topic_id = $m->topic_id; 
        $topic_name = $m->topic_name; 

        $data = array(
           "member_id" => $m->id, 
           "topic_id" => $topic_id, 
           "article_id" => $a->id, 
           "topic_name" => $topic_name, 
           "title" => $a->title, 
          ); 

         $emailersched = ORM::factory('emailersched')->values($data)->save(); 

         unset($m); 

       } 

       $members->__destruct(); 

      //sleep(2); 

      //$m = NULL; 
      } 

      $data = array('sent'=> time()); 

      $query = DB::update('articles') 
        ->set($data) 
        ->where('id', '=', $articles->id) 
        ->execute(); 

      // $articles->sent = time(); 
      // $articles->save(); 


      //} 

     //echo "done"; 
      //$a = NULL; 
      //$articles->__destruct(); 

      $articles = NULL; 
      $topics = NULL; 
      unset($articles); 
      unset($topics); 

      } 

     gc_collect_cycles(); 
     //sleep(60); 

    } 
} 

編輯:另外在我的「內存泄漏」的調查(我繼續遇到我的代碼問題),這裏有一些奇怪的東西,我encoutered:

http://pastebin.com/c7pc5XjW此代碼是在Kohana和FuelPHP上運行 - 相同的基本代碼庫,使用內置的DB模塊,不使用ORM,訪問相同的數據庫。燃料沒有使用油。它是通過公共http訪問Kohana的方式訪問的。

此代碼嘗試處理總共約10k條記錄的50條記錄。

這裏是我的記憶日誌的Kohana:http://pastebin.com/gUiF9D2w

這裏是我的記憶日誌FuelPHP:http://pastebin.com/v8Pzwu77

注意的Kohana在3MB開始,並在7MB結束。然而,FuelPHP開始時大約11Mb,但以11MB結束。雖然Kohana開始小,但在我看來,這確實存在漏洞。

有什麼想法?

+0

什麼版本的Kohana?罪魁禍首會記錄嗎? –

+0

其3.1。我已停用分析。 –

+0

什麼版本的PHP? – egis

回答

0

這是一個多汁的框架戰爭給你:在我的絕望中,我試圖運行相同的代碼給FuelPHP(通過任務在OIL上)。

結果:

-302k記錄處理,在2分鐘內 - 內存泄漏了!

所以,我想這裏的結論是,Kohana代碼庫在某處存在泄漏,不知何故。

3

您是否還確定已禁用數據庫分析?

的config/database.php中

'profiling' => FALSE 

這將導致巨大的泄漏,如果它設置爲TRUE,默認情況下它是。

很容易錯過此設置,只更改引導文件中的主概要分析設置。

+0

這是95%的時間看到內存'泄漏'的原因。這應該在生產中關閉。 – Ikke

0

調試遺留的Kohana 1項目我發現它是config/database.php中的'基準'設置是罪魁禍首。在現有配置中設置爲TRUE會導致內存泄漏,每個數據庫查詢都對應於UPDATE/INSERT中的數據大小或SELECT中結果集的大小。設置爲FALSE並且內存泄漏消失。