- "# CEF/Chromium 記憶體使用量在長期應用中的使用"
IronPDF使用Chromium進行渲染,因此即使在文件被處理和`GC.Collect()`運行後,處理記憶體在生成PDF後仍可能在短時間內保持高位。 "這裡有兩個來源發揮作用:Chromium 的非管理本地分配器和 IronPDF 的瀏覽器選項卡池化。" "在大多數情況下,這是預期的,並不會自動意味著存在記憶體洩漏。"
這適用於IronPDF和Windows及Linux上的`IronPdfEngine`,跨Docker、Kubernetes、VM和伺服器託管環境,以及使用基於Chromium渲染的所有.NET、Java和應用程式。
"## 為什麼記憶體保持升高"
"完成渲染後,有兩個不同的機制會保持記憶體。"
"**Chromium 本地分配器保留:** Chromium 使用大量的非受管理記憶體,存在於 .NET 垃圾收集器之外。" "渲染完成時,Chromium 通常保留這些本地記憶體以供重用,而不是立即將其返還給操作系統。" 因此您的`PdfDocument`物件可以正確處理,運行時可以收集托管物件,而整個進程或容器的記憶體仍然可以讀取到高位。 "這是基於 Chromium 的引擎的正常行為。"
"**瀏覽器池選項卡重用:** IronPDF 可以在一個渲染後保持空閒的瀏覽器選項卡激活,因此下一個開始更快。" "這些選項卡短時間內保留其渲染子進程和 DOM 狀態,即使沒有進行渲染,也會造成明顯的記憶體基線。" "開啟池功能後,您通常會看到計算器在渲染時增長,完成後保持在基線,然後在空閒選項卡超時並清除時逐步下降。"
### 為什麼`GC.Collect()`沒有幫助
`GC.Collect()` 只回收管理的.NET記憶體。 "它不會強制 Chromium 將本地記憶體交還給操作系統,且不會拆除特意保留用於重用的溫 BrowserPool 選項卡。" "即使正確處理和強制收集,任務管理器,Docker,Kubernetes 或工具如 New Relic 顯示的數值也不會立即下降。"
"效果在長期運行的應用程式,共享服務環境以及 Docker 或 Kubernetes 部署中最為明顯。" 對於使用`IronPdfEngine`的Java整合,壓力通常顯示在引擎過程或容器中,而不是JVM堆中。
"## BrowserPool 預設"
"IronPDF 在渲染之間保持少量選項卡溫,從而提高性能。" "預設值為:"
- `BrowserPool.Enabled = true`
- `BrowserPool.MaxIdleTabs = min(max(ProcessorCount / 2, 1), 4)`
- `BrowserPool.IdleTimeoutSeconds = 30`
"因此,即使沒有積極的渲染過程,該過程也可能暫時保持 1 到 4 個空閒選項卡,每個選項卡保留本地記憶體和子進程資源,直到空閒超時過期。" "根據渲染的內容和環境,空閒選項卡可以保留一個明顯的數量,在某些負載下大約為 50 到 100 MB。" "最後一個渲染後,大約 30 秒時間過去後,這種高基線可能會開始逐步下降。"
## 解決方案
"如果環境受記憶限制,首先要調整的是 BrowserPool 設置。" "預設值如下所示:"
```csharp
renderer.RenderingOptions.BrowserPool.Enabled = true; // default
renderer.RenderingOptions.BrowserPool.MaxIdleTabs = 2; // default is CPU/2, clamped to 1-4
renderer.RenderingOptions.BrowserPool.IdleTimeoutSeconds = 30; // default
```
"### 選項 1:完全禁用選項卡池"
"如果希望在每次渲染後實現最確定性的清理,請選擇此選項。"
```csharp
renderer.RenderingOptions.BrowserPool.Enabled = false;
```
"### 選項 2:在不保留空閒選項卡的情況下保留 BrowserPool 啟用"
"保持功能啟用,但避免在渲染之間保持溫選項卡,從而實現確定的每次渲染清理。"
```csharp
renderer.RenderingOptions.BrowserPool.MaxIdleTabs = 0;
```
"### 選項 3:縮短空閒超時"
"中間立場:保持一些重用優勢,但讓記憶在突發流量後更早下降。"
```csharp
renderer.RenderingOptions.BrowserPool.IdleTimeoutSeconds = 10;
```
"**如何選擇:**"
- **`Enabled = false`:** 記憶體穩定性比快速啟動性能更重要。
- **`MaxIdleTabs = 0`:** 您希望有確定的每次渲染清理,而不完全禁用該功能。
- **降低`IdleTimeoutSeconds`:** 您的工作負載以突發方式到來,您希望在每次突發後更快地回收記憶體。
"## 長期運行應用的策略"
"如果您的應用必須持續保持記憶體低,請按順序執行以下操作,先從 BrowserPool 調整開始,然後在需要時轉向過程回收。"
"### 1. 限制並行渲染"
"幾個 Chromium 渲染作業同時運行會導致本地記憶體壓力急劇增加。" "如果並行渲染,請通過信號量限制同時運行的作業數:"
```csharp
private static readonly SemaphoreSlim RenderSemaphore = new(2);
public async Task<t> RunRenderAsync<t>(Func<t> renderWork)
{
await RenderSemaphore.WaitAsync();
try
{
return renderWork();
}
finally
{
RenderSemaphore.Release();
}
}
```
"將您的 IronPDF 渲染調用包裹在限速部分內,以便一次只運行固定數量的作業。"
"### 2. 調整或禁用 BrowserPool"
對於許多記憶體敏感的部署,這是最有效的第一步。完全禁用BrowserPool,設置`IdleTimeoutSeconds`以應對突發工作負載。 "這些中的任何一項都可以縮小持續的後渲染基線,而不需完全重啟策略。"
"### 3. 在獨立工作者中隔離渲染"
"在生產系統中將 PDF 渲染移出主應用是強大的一步。" "主應用保持穩定,渲染工作者可以自行重新啟動,當該工作者退出時,本地 Chromium 記憶充分釋放。" 在依賴於回收之前,請確認禁用BrowserPool或設置`MaxIdleTabs = 0`是否已經能為您提供可預測的每次渲染清理。在Docker或Kubernetes環境中、背景作業系統以及需要更嚴格記憶體隔離的API平台中,隔離方法是最有效的。
"### 4. 需要時僅回收工作者"
"在有硬記憶上限且 BrowserPool 調整仍不足時,在設計數量的作業後回收渲染過程或工作者容器。" "這可能意味著在固定批處理大小後重新啟動專用工作者,旋轉 Kubernetes 中的引擎容器,或將渲染隔離到可以獨立重啟的服務中。" "稍後步驟,不是您的首選。"
"## 可能是記憶體洩漏的時候"
"渲染後記憶保持升高並不一定意味著洩漏。" "基於 Chromium 的渲染有兩種型別的重用需要了解:**分配器層次重用**,指的是 Chromium 內部保留本地記憶體頁(正常的,無法直接控制),以及 **選項卡層次重用**,指的是 BrowserPool 在渲染之間保持完整選項卡活躍(可配置的,且通常是您在監控工具中看到的最大貢獻者)。"
"當記憶在渲染時上升,穩定而不是無限增長,之後短時間保持升高,然後在空閒選項卡超時時下降或為下一次渲染保持可用時,這通常是預期的模式。"
"進一步調查時:"
"- 記憶在相似的工作負載下保持上升而不穩定下來"
"- 即使減少並發,也保持增長"
- 即使在禁用BrowserPool或設置`MaxIdleTabs = 0`後,記憶體仍然持續增長
"- 已通過最少重現展示出相同的模式且受控輸入的情況中"
"## 何時聯繫支援"
"如果您能夠重現以下全部情況,請聯繫 [技術支援](/troubleshooting/engineering-support-for-ironpdf/):"
"1. 記憶在控制的工作負載下抵達穩定而不是持續增長"
"2. 限制并發后問題依然存在"
3. 在禁用BrowserPool或設置`MaxIdleTabs = 0`後,問題仍然存在
"4. 您能夠使用最小的範本專案重現它"
"開票時,請包括您的 IronPDF 版本,OS 和託管環境,Docker 或 Kubernetes 詳細資訊(如適用),程式語言,渲染頻率和并發級別,記憶圖或監控截圖,以及最小可重現的專案。"
Ask ChatGPT about this page
Ask Gemini about this page
Ask Perplexity about this page
"# CEF/Chromium 記憶體使用量在長期應用中的使用"
IronPDF使用Chromium進行渲染,因此即使在文件被處理和GC.Collect()運行後,處理記憶體在生成PDF後仍可能在短時間內保持高位。 "這裡有兩個來源發揮作用:Chromium 的非管理本地分配器和 IronPDF 的瀏覽器選項卡池化。" "在大多數情況下,這是預期的,並不會自動意味著存在記憶體洩漏。"
這適用於IronPDF和Windows及Linux上的IronPdfEngine,跨Docker、Kubernetes、VM和伺服器託管環境,以及使用基於Chromium渲染的所有.NET、Java和應用程式。
"## 為什麼記憶體保持升高"
"完成渲染後,有兩個不同的機制會保持記憶體。"
"Chromium 本地分配器保留: Chromium 使用大量的非受管理記憶體,存在於 .NET 垃圾收集器之外。" "渲染完成時,Chromium 通常保留這些本地記憶體以供重用,而不是立即將其返還給操作系統。" 因此您的PdfDocument物件可以正確處理,運行時可以收集托管物件,而整個進程或容器的記憶體仍然可以讀取到高位。 "這是基於 Chromium 的引擎的正常行為。"
"瀏覽器池選項卡重用: IronPDF 可以在一個渲染後保持空閒的瀏覽器選項卡激活,因此下一個開始更快。" "這些選項卡短時間內保留其渲染子進程和 DOM 狀態,即使沒有進行渲染,也會造成明顯的記憶體基線。" "開啟池功能後,您通常會看到計算器在渲染時增長,完成後保持在基線,然後在空閒選項卡超時並清除時逐步下降。"
為什麼GC.Collect()沒有幫助
GC.Collect() 只回收管理的.NET記憶體。 "它不會強制 Chromium 將本地記憶體交還給操作系統,且不會拆除特意保留用於重用的溫 BrowserPool 選項卡。" "即使正確處理和強制收集,任務管理器,Docker,Kubernetes 或工具如 New Relic 顯示的數值也不會立即下降。"
"效果在長期運行的應用程式,共享服務環境以及 Docker 或 Kubernetes 部署中最為明顯。" 對於使用IronPdfEngine的Java整合,壓力通常顯示在引擎過程或容器中,而不是JVM堆中。
"## BrowserPool 預設"
"IronPDF 在渲染之間保持少量選項卡溫,從而提高性能。" "預設值為:"
BrowserPool.Enabled = true
BrowserPool.MaxIdleTabs = min(max(ProcessorCount / 2, 1), 4)
BrowserPool.IdleTimeoutSeconds = 30
"因此,即使沒有積極的渲染過程,該過程也可能暫時保持 1 到 4 個空閒選項卡,每個選項卡保留本地記憶體和子進程資源,直到空閒超時過期。" "根據渲染的內容和環境,空閒選項卡可以保留一個明顯的數量,在某些負載下大約為 50 到 100 MB。" "最後一個渲染後,大約 30 秒時間過去後,這種高基線可能會開始逐步下降。"
解決方案
"如果環境受記憶限制,首先要調整的是 BrowserPool 設置。" "預設值如下所示:"
renderer.RenderingOptions.BrowserPool.Enabled = true; // default
renderer.RenderingOptions.BrowserPool.MaxIdleTabs = 2; // default is CPU/2, clamped to 1-4
renderer.RenderingOptions.BrowserPool.IdleTimeoutSeconds = 30; // default
renderer.RenderingOptions.BrowserPool.Enabled = true; // default
renderer.RenderingOptions.BrowserPool.MaxIdleTabs = 2; // default is CPU/2, clamped to 1-4
renderer.RenderingOptions.BrowserPool.IdleTimeoutSeconds = 30; // default
C#
"### 選項 1:完全禁用選項卡池"
"如果希望在每次渲染後實現最確定性的清理,請選擇此選項。"
renderer.RenderingOptions.BrowserPool.Enabled = false;
renderer.RenderingOptions.BrowserPool.Enabled = false;
C#
"### 選項 2:在不保留空閒選項卡的情況下保留 BrowserPool 啟用"
"保持功能啟用,但避免在渲染之間保持溫選項卡,從而實現確定的每次渲染清理。"
renderer.RenderingOptions.BrowserPool.MaxIdleTabs = 0;
renderer.RenderingOptions.BrowserPool.MaxIdleTabs = 0;
C#
"### 選項 3:縮短空閒超時"
"中間立場:保持一些重用優勢,但讓記憶在突發流量後更早下降。"
renderer.RenderingOptions.BrowserPool.IdleTimeoutSeconds = 10;
renderer.RenderingOptions.BrowserPool.IdleTimeoutSeconds = 10;
C#
"如何選擇:"
Enabled = false: 記憶體穩定性比快速啟動性能更重要。
MaxIdleTabs = 0: 您希望有確定的每次渲染清理,而不完全禁用該功能。
- 降低
IdleTimeoutSeconds: 您的工作負載以突發方式到來,您希望在每次突發後更快地回收記憶體。
"## 長期運行應用的策略"
"如果您的應用必須持續保持記憶體低,請按順序執行以下操作,先從 BrowserPool 調整開始,然後在需要時轉向過程回收。"
"### 1. 限制並行渲染"
"幾個 Chromium 渲染作業同時運行會導致本地記憶體壓力急劇增加。" "如果並行渲染,請通過信號量限制同時運行的作業數:"
private static readonly SemaphoreSlim RenderSemaphore = new(2);
public async Task<t> RunRenderAsync<t>(Func<t> renderWork)
{
await RenderSemaphore.WaitAsync();
try
{
return renderWork();
}
finally
{
RenderSemaphore.Release();
}
}
private static readonly SemaphoreSlim RenderSemaphore = new(2);
public async Task<t> RunRenderAsync<t>(Func<t> renderWork)
{
await RenderSemaphore.WaitAsync();
try
{
return renderWork();
}
finally
{
RenderSemaphore.Release();
}
}
C#
"將您的 IronPDF 渲染調用包裹在限速部分內,以便一次只運行固定數量的作業。"
"### 2. 調整或禁用 BrowserPool"
對於許多記憶體敏感的部署,這是最有效的第一步。完全禁用BrowserPool,設置IdleTimeoutSeconds以應對突發工作負載。 "這些中的任何一項都可以縮小持續的後渲染基線,而不需完全重啟策略。"
"### 3. 在獨立工作者中隔離渲染"
"在生產系統中將 PDF 渲染移出主應用是強大的一步。" "主應用保持穩定,渲染工作者可以自行重新啟動,當該工作者退出時,本地 Chromium 記憶充分釋放。" 在依賴於回收之前,請確認禁用BrowserPool或設置MaxIdleTabs = 0是否已經能為您提供可預測的每次渲染清理。在Docker或Kubernetes環境中、背景作業系統以及需要更嚴格記憶體隔離的API平台中,隔離方法是最有效的。
"### 4. 需要時僅回收工作者"
"在有硬記憶上限且 BrowserPool 調整仍不足時,在設計數量的作業後回收渲染過程或工作者容器。" "這可能意味著在固定批處理大小後重新啟動專用工作者,旋轉 Kubernetes 中的引擎容器,或將渲染隔離到可以獨立重啟的服務中。" "稍後步驟,不是您的首選。"
"## 可能是記憶體洩漏的時候"
"渲染後記憶保持升高並不一定意味著洩漏。" "基於 Chromium 的渲染有兩種型別的重用需要了解:分配器層次重用,指的是 Chromium 內部保留本地記憶體頁(正常的,無法直接控制),以及 選項卡層次重用,指的是 BrowserPool 在渲染之間保持完整選項卡活躍(可配置的,且通常是您在監控工具中看到的最大貢獻者)。"
"當記憶在渲染時上升,穩定而不是無限增長,之後短時間保持升高,然後在空閒選項卡超時時下降或為下一次渲染保持可用時,這通常是預期的模式。"
"進一步調查時:"
"- 記憶在相似的工作負載下保持上升而不穩定下來"
"- 即使減少並發,也保持增長"
- 即使在禁用BrowserPool或設置
MaxIdleTabs = 0後,記憶體仍然持續增長
"- 已通過最少重現展示出相同的模式且受控輸入的情況中"
"## 何時聯繫支援"
"如果您能夠重現以下全部情況,請聯繫 技術支援:"
"1. 記憶在控制的工作負載下抵達穩定而不是持續增長"
"2. 限制并發后問題依然存在"
3. 在禁用BrowserPool或設置MaxIdleTabs = 0後,問題仍然存在
"4. 您能夠使用最小的範本專案重現它"
"開票時,請包括您的 IronPDF 版本,OS 和託管環境,Docker 或 Kubernetes 詳細資訊(如適用),程式語言,渲染頻率和并發級別,記憶圖或監控截圖,以及最小可重現的專案。"

技術作家
Curtis Chau擁有Carleton大學的電腦科學學士學位,專精於前端開發,擁有Node.js、TypeScript、JavaScript和React的專業知識。Curtis熱衷於建立直觀且美觀的使用者介面,喜愛使用現代框架並建立結構良好、視覺吸引力的手冊。
...
閱讀更多