2011-08-16 2 views
1

Je filigranage des documents, et je ne veux pas les charger complètement en mémoire, car ils peuvent être assez volumineux. J'ai trouvé que RandomAccessFileOrArray tamponnait la lecture, ce qui se passe bien mais reste trop chargé à mon goût. C'est-à-dire que, après avoir chargé un fichier PDF de 5 Mo, la mémoire utilisée augmente de 23 Mo.! Et quand je commence le tatouage, il saute un autre 27Mb! Après que la mémoire utilisée augmente progressivement, mais pas horriblement.Gestion de la mémoire iText - PdfReader/Watermarking charge trop

Y a-t-il une raison à un tel comportement? Savez-vous un moyen de définir la taille de la mémoire tampon du PdfReader ou RandomAccessFileOrArray ou autre chose?

Merci de votre participation. La méthode printMem montre l'état de la mémoire en affichant free-used-total.

Voici mon code

printMem("Before load"); 
    PdfReader reader = null; 
    try { 
     reader = new PdfReader(new RandomAccessFileOrArray(new FileInputStream("C:/TEMP/zip/100258.pdf")),null); 
     printMem("After load"); 
     FileOutputStream out = new FileOutputStream(f); 
     PdfStamper stamp = new PdfStamper(reader, out); 

     int numPages = reader.getNumberOfPages(); 
     int page=1; 
     BaseFont baseFont = 
      BaseFont.createFont(BaseFont.HELVETICA_BOLDOBLIQUE, 
       BaseFont.WINANSI, BaseFont.EMBEDDED); 
     float width; 
     float height; 

     while (page <= numPages) { 
      printMem("Page " + page); 
      PdfContentByte cb = stamp.getOverContent(page); 
      height = reader.getPageSizeWithRotation(page).getHeight()/2; 
      width = reader.getPageSizeWithRotation(page).getWidth()/2; 

      cb.saveState(); 
      cb.setColorFill(MEDIUM_GRAY); 

      // Primary Text 
      cb.beginText(); 
      cb.setFontAndSize(baseFont, PRIMARY_FONT_SIZE); 
      cb.showTextAligned(Element.ALIGN_CENTER, "WatermarkText", width, 
        height, TEXT_TILT_ANGLE); 
      cb.endText(); 

      cb.restoreState(); 
      page++; 
     } 
     stamp.close(); 
    } catch(Throwable e) { 
     reader = null; 
     System.gc(); 
    } 

Et est ici la sortie partielle:

Before load | 1566248160 6615840 1572864000 
After load | 1542392472 30471528 1572864000 
Page 1 | 1515096880 57767120 1572864000 
Page 2 | 1515095992 57768008 1572864000 
Page 47 | 1512998840 59865160 1572864000 
Page 48 | 1512998840 59865160 1572864000 
+0

Avez-vous essayé de forcer le ramasse-miettes pour voir s'il s'agit vraiment d'une fuite de mémoire, ou si c'est juste que la mémoire n'a pas été libérée? – Milhous

+0

Juste un commentaire sur l'utilisation de la mémoire et la taille du pdf vs la quantité de pages. L'utilisation de la mémoire dépend moins de la taille du fichier que du nombre de pages. Par exemple: un PDF d'une page de 1 Mo nécessite moins de mémoire qu'un pdf de 100 pages de 10 Ko. Votre code semble très bien avec la lecture partielle par RandomAccessFileOrArray. – Eriksberger

Répondre

2

Le document est lu que partiellement si vous construisez le RandomAccessFileOrArray avec une chaîne qui contient le chemin du fichier (par exemple nouveau RandomAccessFileOrArray ("/ chemin/vers/pdf");). Avec un InputStream ou une URL, le document entier est copié dans un tableau d'octets interne.