2016-07-26 4 views
1

La plupart des exemples iText7 se réfèrent à l'utilisation de PdfFontFactory.createFont() pour obtenir des poignées vers des instances PdfFont pour les opérations de texte. Avec modération, c'est bien ... mais PdfFont est un objet assez lourd (PdfEncoding) qui ne semble pas disparaître tant que le PdfDocument n'est pas fermé. Ainsi, le bloc innocent suivant est avalent va de la mémoire:Stratégie iText7 pour limiter la consommation de mémoire de PdfFont

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

une tentative triviale à une solution à l'aide a échoué car il statics semble PdfFont cas ne peuvent pas être utilisés dans plus d'un PDFDocument. Et parce que mon réel cas est plus complexe que l'exemple ci-dessus, je ne veux pas avoir à passer un tas de références PdfFont à travers une pile assez profonde.

  1. dans l'API iText7, il n'y a pas moyen d'itérer sur son existants de PdfFont pour le PDFDocument (est là?)
  2. est la règle pour l'utilisation PdfFont simplement que a) il peut être utilisé autant de fois que vous le souhaitez b) dans une seule instance PDFDocument

(c.-à-est une solution possible ici aux instances de PdfFont simplement cache à l'aide d'une clé PDFDocument + PdfFontProgram?)

+0

le cacheKey suggéré ci-dessus est une mauvaise idée. Il semble que les instances de FontProgram soient mises en cache dans une Map statique, ce qui signifie qu'une clé de cache weakRef sera toujours utilisée (et par conséquent, le PdfDocument restera en mémoire). Une meilleure approche semble être une carte des cartes - WeakHashMap > –

Répondre

0

de PdfFonts semblent être cacheable/réutilisable au niveau PDFDocument. Si vous utilisez un WeakHashMap comme cache, les clés et les valeurs doivent être des références faibles. par exemple

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(); 
} 
soins

devraient également être prises pour API iText qui appelle PdfFontFactory lui-même, tels que les dérivés Barcode1D configurés pour afficher une valeur lisible par l'homme (par exemple la création d'une nouvelle instance Barcode1D par page w/out appeler setFont() sera rapidement épuiser la mémoire pour les documents volumineux)