2016-07-26 19 views
1

Die meisten iText7-Beispiele beziehen sich auf die Verwendung von PdfFontFactory.createFont(), um Handles für PdfFont-Instanzen für Textoperationen zu erhalten. Mit Mäßigung ist das in Ordnung ... aber PdfFont ist ein ziemlich schweres Objekt (PdfEncoding), das erst verschwindet, wenn das PdfDocument geschlossen ist. Also folgende unschuldig Block ist gonna verschlingen Speicher:iText7-Strategie zur Begrenzung der Speicherbelegung von PdfFont

for (int i = 0; i < someLargeNumber; i++) { 
    list.add(
     new ListItem("never gonna give") 
     .setFont(PdfFontFactory.createFont("Helvetica-Oblique")) 
    ) 
} 

trivialer Lösungsversuch Statik mit schlug fehl, da es PdfFont Instanzen erscheint, können nicht über mehr als eine PDFDocument verwendet werden. Und weil mein tatsächlicher Fall komplexer ist als das obige Beispiel, möchte ich nicht eine Menge PdfFont-Referenzen über einen ziemlich tiefen Stapel weitergeben müssen.

  1. in der iText7 API, gibt es keine Möglichkeit für die PDFDocument bestehende PdfFont des iterieren (gibt es?)
  2. ist die Regel für PdfFont Nutzung einfach, dass a) es so oft verwendet werden kann, wie Sie wollen b) innerhalb einer einzigen PDFDocument Instanz

(dh eine mögliche Lösung hier einfach Cache PdfFont Instanzen eines PDFDocument + PdfFontProgram Schlüssel?)

+0

der oben vorgeschlagene cacheKey ist eine schlechte Idee. Es sieht so aus, als ob FontProgram-Instanzen in einer statischen Map zwischengespeichert werden, was bedeutet, dass ein weakRef-Cache-Schlüssel immer verwendet wird (und dadurch auch das PdfDocument im Speicher hält). Ein besserer Ansatz scheint eine Map of Maps zu sein - WeakHashMap > –

Antwort

0

PdfFonts erscheint zwischenspeicherbar/wiederverwendbar am PDFDocument Niveau. Wenn Sie eine WeakHashMap als Cache verwenden, müssen sowohl die Schlüssel als auch die Werte schwache Refs sein. Beispiel

private static WeakHashMap<PdfDocument, Map<String, WeakReference<PdfFont>>> fontCache = new WeakHashMap<>(); 

public static synchronized PdfFont createFont(PdfDocument forDocument, String path) throws IOException { 
    Map<String, WeakReference<PdfFont>> documentFontMap = fontCache.get(forDocument); 
    if (documentFontMap == null) { 
     documentFontMap = new HashMap<>(); 
     fontCache.put(forDocument, documentFontMap); 
    } 
    WeakReference<PdfFont> font = documentFontMap.get(path); 
    if (font == null) { 
     font = new WeakReference<>(PdfFontFactory.createFont(path)); 
     documentFontMap.put(path, font); 
    } 
    return font.get(); 
} 

Sorgfalt sollte auch für iText API genommen werden, die PdfFontFactory sich selbst aufruft, wie Barcode1D Derivate einen für Menschen lesbaren Wert anzuzeigen konfiguriert (dh eine neue Barcode1D Instanz pro Seite w/out setFont() aufrufen Schaffung wird schnell Speicher für große Dokumente)