2012-11-06 58 views
0

我的應用程序需要生成一個包含一堆圖形的pdf文件。PHP/JpGraph - 功能完成後未釋放內存

情況:我使用pdf生成FPDF和圖形使用JpGraph。我的代碼從數據庫獲取圖形數據並迭代,爲每個包含所有JpGraph代碼的圖形調用一個函數,設置圖形樣式,並將其作爲png文件緩存在服務器上的緩存文件夾中。然後,FPDF將這些圖像放在pdf中,並將其提供給瀏覽器。

問題:當圖表數量超過某個數字時,我得到的PHP內存錯誤。 AFAICT這不是一個FPDF問題:在試圖診斷問題時,我生成了更多更大的文檔,其中包含更多(預生成)的等效大小的圖形和圖像。問題似乎是,當函數完成時,用於在圖形渲染函數中渲染圖形的內存不會被釋放。這是基於這樣一個事實,即如果我在函數中調用memory_get_peak_usage,我會得到一堆數量不斷增加的數字,每次調用函數時都會有一個數字,直到64MB的停止位置。

My圖表生成腳本看起來是這樣的:

function barChart($filename, $ydata, $xdata){ 

// Create the graph. These two calls are always required 
$graph = new Graph(900,500); 
$graph->SetScale('textlin'); 

//(bunch of styling stuff) 

// Create the bar plot 
$bplot=new BarPlot($ydata); 

// Add the plot to the graph 
$graph->Add($bplot); 

//(more styling stuff) 


// Display the graph 
$graph->Stroke($filename); 

$graph = null; 
$bplot = null; 

unset($graph); 
unset($bplot); 

echo "<br><br>".(memory_get_peak_usage(true)/1048576)."<br><br>"; 
} 

正如你所看到的,我已經試過解封,並抵消了圖形和bplot對象,雖然我的理解是,這不應該是必要的。當函數完成時,Graph和Bplot實例使用的內存不應該全部釋放嗎?或者這可能是一個JpGraph內存泄漏? (我搜索了高和低,並找不到任何人抱怨這一點)。這是我第一個遠程資源豐富的PHP項目,所以我可能會錯過一些明顯的東西。

回答

5

我有同樣的問題,結果發現只是一個小時左右後的溶液。

問題是,jpgraph每次加載一組默認的字體文件集 a圖創建。我找不到一種卸載字體的方法,所以我做了一些小改動,以便它只加載一次字體。

要修復您的安裝,修改「gd_image.inc.php」如下:

添加下列附近的某處文件的開頭(之前的CLASS圖片):

// load fonts only once, and define a constant for them 
define("GD_FF_FONT0", imageloadfont(dirname(__FILE__) . "/fonts/FF_FONT0.gdf")); 
define("GD_FF_FONT1", imageloadfont(dirname(__FILE__) . "/fonts/FF_FONT1.gdf")); 
define("GD_FF_FONT2", imageloadfont(dirname(__FILE__) . "/fonts/FF_FONT2.gdf")); 
define("GD_FF_FONT1_BOLD", imageloadfont(dirname(__FILE__) . "/fonts/FF_FONT1-Bold.gdf")); 
define("GD_FF_FONT2_BOLD", imageloadfont(dirname(__FILE__) . "/fonts/FF_FONT2-Bold.gdf")); 
與此

$this->ff_font0 = imageloadfont(dirname(__FILE__) . "/fonts/FF_FONT0.gdf"); 
$this->ff_font1 = imageloadfont(dirname(__FILE__) . "/fonts/FF_FONT1.gdf"); 
$this->ff_font2 = imageloadfont(dirname(__FILE__) . "/fonts/FF_FONT2.gdf"); 
$this->ff_font1_bold = imageloadfont(dirname(__FILE__) . "/fonts/FF_FONT1-Bold.gdf"); 
$this->ff_font2_bold = imageloadfont(dirname(__FILE__) . "/fonts/FF_FONT2-Bold.gdf"); 

然後在圖像類構造函數(線91-95)的端部,代替這個

$this->ff_font0 = GD_FF_FONT0; 
$this->ff_font1 = GD_FF_FONT1; 
$this->ff_font2 = GD_FF_FONT2; 
$this->ff_font1_bold = GD_FF_FONT1_BOLD; 
$this->ff_font2_bold = GD_FF_FONT2_BOLD; 

我沒有測試這與多個版本的PHP或Jpgraph,但它應該工作正常。因人而異。

2

你可以嘗試使用PHP> = 5.3垃圾收集

gc_enable() + gc_collect_cycles()

http://php.net/manual/en/features.gc.php

+0

感謝這個想法 - 我的生產服務器是(並且必須)運行5.2,但我已經在本地測試了5.3,在相同的內存限制下,新的gc似乎沒有幫助。我想這是要麼調試在JpGraph中明顯不良的內存處理,通過運行多個線程破解它,或者更改圖形系統... – John