Hohe Spitzenarbeitsspeicher während ReadPdf auf großen PDFs

This article was translated from English: Does it need improvement?
Translated
View the article in English

Ein Aufruf von BarcodeReader.ReadPdf() für ein ganzes großes PDF rendert jede angeforderte Seite für das Scannen bei der konfigurierten DPI, sodass der maximale Speicherverbrauch mit der Seitenanzahl und der Auflösung skaliert, anstatt konstant zu bleiben. Bei einer 248-seitigen, 80 MB großen Datei bei 300 DPI lag der Arbeitsspeicher zwischen 3 GB und 8 GB mit Spitzen von bis zu 12 GB, was in speicherbegrenzten Umgebungen zum Scheitern führen kann.

BarcodeReader.ReadPdf() verarbeitet jede ihm übergebene Seite in einem einzigen Vorgang. Wenn die gesamte Seitenreihe eines großen, hochauflösenden Dokuments auf einmal gelesen wird, werden alle diese Seiten zusammen im Arbeitsspeicher gehalten, sodass die Spitzenverwendung mit der Größe des Seitensatzes wächst. Dies spiegelt wider, wie die Lektüre in Stapeln erfolgt, nicht jedoch ein bestätigter Defekt in IronBarcode.

Lösung

1. Lesen in festen Seitenblöcken

Teilen Sie das Dokument mit PdfBarcodeReaderOptions.PageNumbers in feste Seitenabschnitte, sodass jeweils nur ein Abschnitt im Speicher ist. Ein kleinerer chunkSize senkt den maximalen Speicherbedarf, fügt jedoch mehr Durchläufe hinzu. Stimmen Sie es also auf das Speicherlimit der Umgebung ab.

var barcodeMetadata = new List<BarcodeResult>();
var pageChunks = Enumerable.Range(1, pdf.PageCount)
    .GroupBy(i => i / 50)
    .Select(g => g.ToArray())
    .ToList();
foreach (var chunk in pageChunks)
{
    var readerOptions = new PdfBarcodeReaderOptions
    {
        ExpectMultipleBarcodes = true,
        ExpectBarcodeTypes = IronBarCode.BarcodeEncoding.AllOneDimensional,
        Speed = ReadingSpeed.Detailed,
        ScanMode = BarcodeScanMode.OnlyDetectionModel,
        DPI = 300,
        PageNumbers = chunk
    };
    Console.WriteLine($"Processing pages: Pages {chunk.First()}-{chunk.Last()}");
    var chunkResult = BarcodeReader.ReadPdf(pdf.Stream, readerOptions);
    if (chunkResult != null && chunkResult.Count > 0)
    {
        barcodeMetadata.AddRange(chunkResult);
    }
    // Optional memory pressure relief
    GC.Collect();
    GC.WaitForPendingFinalizers();
}
Console.WriteLine($"Total barcodes found: {barcodeMetadata.Count}");
var barcodeMetadata = new List<BarcodeResult>();
var pageChunks = Enumerable.Range(1, pdf.PageCount)
    .GroupBy(i => i / 50)
    .Select(g => g.ToArray())
    .ToList();
foreach (var chunk in pageChunks)
{
    var readerOptions = new PdfBarcodeReaderOptions
    {
        ExpectMultipleBarcodes = true,
        ExpectBarcodeTypes = IronBarCode.BarcodeEncoding.AllOneDimensional,
        Speed = ReadingSpeed.Detailed,
        ScanMode = BarcodeScanMode.OnlyDetectionModel,
        DPI = 300,
        PageNumbers = chunk
    };
    Console.WriteLine($"Processing pages: Pages {chunk.First()}-{chunk.Last()}");
    var chunkResult = BarcodeReader.ReadPdf(pdf.Stream, readerOptions);
    if (chunkResult != null && chunkResult.Count > 0)
    {
        barcodeMetadata.AddRange(chunkResult);
    }
    // Optional memory pressure relief
    GC.Collect();
    GC.WaitForPendingFinalizers();
}
Console.WriteLine($"Total barcodes found: {barcodeMetadata.Count}");
Imports System
Imports System.Collections.Generic
Imports System.Linq
Imports IronBarCode

Dim barcodeMetadata As New List(Of BarcodeResult)()
Dim pageChunks = Enumerable.Range(1, pdf.PageCount) _
    .GroupBy(Function(i) i \ 50) _
    .Select(Function(g) g.ToArray()) _
    .ToList()

For Each chunk In pageChunks
    Dim readerOptions As New PdfBarcodeReaderOptions With {
        .ExpectMultipleBarcodes = True,
        .ExpectBarcodeTypes = BarcodeEncoding.AllOneDimensional,
        .Speed = ReadingSpeed.Detailed,
        .ScanMode = BarcodeScanMode.OnlyDetectionModel,
        .DPI = 300,
        .PageNumbers = chunk
    }
    Console.WriteLine($"Processing pages: Pages {chunk.First()}-{chunk.Last()}")
    Dim chunkResult = BarcodeReader.ReadPdf(pdf.Stream, readerOptions)
    If chunkResult IsNot Nothing AndAlso chunkResult.Count > 0 Then
        barcodeMetadata.AddRange(chunkResult)
    End If
    ' Optional memory pressure relief
    GC.Collect()
    GC.WaitForPendingFinalizers()
Next

Console.WriteLine($"Total barcodes found: {barcodeMetadata.Count}")
$vbLabelText   $csharpLabel

Jede Iteration liest nur die in PageNumbers genannten Seiten, sodass der Speicher zwischen den Abschnitten herunterfährt, anstatt im gesamten Dokument zuzunehmen.

2. Cache der PDF-Stream und Rücksetzen der Position

Lesen Sie den Stream einmal vor der Schleife in eine lokale Variable und spulen Sie ihn dann für jeden Abschnitt zurück. Die Stream-Eigenschaft kann bei jedem Zugriff eine Zuordnung vornehmen, speichern Sie sie daher in var pdfStream = pdf.Stream; und rufen Sie pdfStream.Seek(0, SeekOrigin.Begin) vor jedem Abschnitts-Read auf.

3. Erstellen Sie die Leseroptionen einmal

Erstellen Sie PdfBarcodeReaderOptions außerhalb der Schleife und ändern Sie pro Abschnitt nur PageNumbers, anstatt bei jeder Iteration ein neues Optionsobjekt zuzuweisen.

4. Vorerstellen der Ergebnisliste

Initialisieren Sie die Ergebnisliste mit einer geschätzten Kapazität, um wiederholtes internes Verdoppeln des Arrays zu vermeiden, wenn Ergebnisse hinzugefügt werden. Die Wiederholung schätzt ungefähr einen Barcode pro zehn Seiten als Ausgangszahl.

Curtis Chau
Technischer Autor

Curtis Chau hat einen Bachelor-Abschluss in Informatik von der Carleton University und ist spezialisiert auf Frontend-Entwicklung mit Expertise in Node.js, TypeScript, JavaScript und React. Leidenschaftlich widmet er sich der Erstellung intuitiver und ästhetisch ansprechender Benutzerschnittstellen und arbeitet gerne mit modernen Frameworks sowie der Erstellung gut strukturierter, optisch ansprechender ...

Weiterlesen
Bereit anzufangen?
Nuget Downloads 2,317,217 | Version: 2026.7 gerade veröffentlicht
Still Scrolling Icon

Scrollst du immer noch?

Sie brauchen schnell einen Beweis? PM > Install-Package BarCode
Führen Sie ein Beispiel aus und beobachten Sie, wie Ihre Zeichenkette zu einem BarCode wird.