Uploaded image for project: 'PDFBox'
  1. PDFBox
  2. PDFBOX-3080

TrueTypeFont synchronization

    XMLWordPrintableJSON

Details

    • Improvement
    • Status: Closed
    • Minor
    • Resolution: Fixed
    • 2.0.0
    • 3.0.0 PDFBox
    • FontBox
    • Debian, java version "1.8.0_60"
      Java(TM) SE Runtime Environment (build 1.8.0_60-b27)
      Java HotSpot(TM) 64-Bit Server VM (build 25.60-b23, mixed mode)

    Description

      The use case is rasterize pdf to png.

      On high load, a lot of threads are blocked in the TrueTypeFont.getHorizontalMetrics() or getHorinzontalHeader() methods.

      Jstack snippet:

      Thread 21999: (state = BLOCKED)
       - org.apache.fontbox.ttf.TrueTypeFont.getHorizontalMetrics() @bci=6, line=231 (Compiled frame)
       - org.apache.fontbox.ttf.TrueTypeFont.getAdvanceWidth(int) @bci=1, line=439 (Compiled frame)
       - org.apache.pdfbox.pdmodel.font.PDTrueTypeFont.getWidthFromFont(int) @bci=11, line=324 (Compiled frame)
       - org.apache.pdfbox.rendering.PageDrawer.drawGlyph2D(org.apache.pdfbox.rendering.Glyph2D, org.apache.pdfbox.pdmodel.font.PDFont, int, org.apache.pdfbox.util.Vector, java.awt.geom.AffineTransform)
       @bci=39, line=350 (Compiled frame)
       - org.apache.pdfbox.rendering.PageDrawer.showFontGlyph(org.apache.pdfbox.util.Matrix, org.apache.pdfbox.pdmodel.font.PDFont, int, java.lang.String, org.apache.pdfbox.util.Vector) @bci=34, line=32
      5 (Compiled frame)
       - org.apache.pdfbox.contentstream.PDFStreamEngine.showGlyph(org.apache.pdfbox.util.Matrix, org.apache.pdfbox.pdmodel.font.PDFont, int, java.lang.String, org.apache.pdfbox.util.Vector) @bci=32, li
      ne=728 (Compiled frame)
       - org.apache.pdfbox.contentstream.PDFStreamEngine.showText(byte[]) @bci=240, line=685 (Compiled frame)
       - org.apache.pdfbox.contentstream.PDFStreamEngine.showTextString(byte[]) @bci=2, line=553 (Compiled frame)
       - org.apache.pdfbox.contentstream.operator.text.ShowText.process(org.apache.pdfbox.contentstream.operator.Operator, java.util.List) @bci=45, line=50 (Compiled frame)
       - org.apache.pdfbox.contentstream.PDFStreamEngine.processOperator(org.apache.pdfbox.contentstream.operator.Operator, java.util.List) @bci=35, line=799 (Compiled frame)
       - org.apache.pdfbox.contentstream.PDFStreamEngine.processStreamOperators(org.apache.pdfbox.contentstream.PDContentStream) @bci=69, line=461 (Compiled frame)
       - org.apache.pdfbox.contentstream.PDFStreamEngine.processStream(org.apache.pdfbox.contentstream.PDContentStream) @bci=63, line=438 (Compiled frame)
       - org.apache.pdfbox.contentstream.PDFStreamEngine.showForm(org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject) @bci=19, line=178 (Interpreted frame)
       - org.apache.pdfbox.contentstream.operator.graphics.DrawObject.process(org.apache.pdfbox.contentstream.operator.Operator, java.util.List) @bci=162, line=70 (Interpreted frame)
       - org.apache.pdfbox.contentstream.PDFStreamEngine.processOperator(org.apache.pdfbox.contentstream.operator.Operator, java.util.List) @bci=35, line=799 (Compiled frame)
       - org.apache.pdfbox.contentstream.PDFStreamEngine.processStreamOperators(org.apache.pdfbox.contentstream.PDContentStream) @bci=69, line=461 (Compiled frame)
       - org.apache.pdfbox.contentstream.PDFStreamEngine.processStream(org.apache.pdfbox.contentstream.PDContentStream) @bci=63, line=438 (Compiled frame)
       - org.apache.pdfbox.contentstream.PDFStreamEngine.processPage(org.apache.pdfbox.pdmodel.PDPage) @bci=19, line=149 (Interpreted frame)
       - org.apache.pdfbox.rendering.PageDrawer.drawPage(java.awt.Graphics, org.apache.pdfbox.pdmodel.common.PDRectangle) @bci=93, line=180 (Interpreted frame)
       - org.apache.pdfbox.rendering.PDFRenderer.renderPage(org.apache.pdfbox.pdmodel.PDPage, java.awt.Graphics2D, int, int, float, float) @bci=160, line=208 (Interpreted frame)
       - org.apache.pdfbox.rendering.PDFRenderer.renderImage(int, float, org.apache.pdfbox.rendering.ImageType) @bci=166, line=139 (Interpreted frame)
       - org.apache.pdfbox.rendering.PDFRenderer.renderImageWithDPI(int, float, org.apache.pdfbox.rendering.ImageType) @bci=7, line=94 (Interpreted frame)
      [...]
      

      These methods are synchronized. (I think because of initialization block.)

      When I change from:

      actual
      public synchronized HorizontalHeaderTable getHorizontalHeader() throws IOException {
          HorizontalHeaderTable horizontalHeader = (HorizontalHeaderTable)tables.get( HorizontalHeaderTable.TAG );
          if (horizontalHeader != null && !horizontalHeader.getInitialized()) {
              readTable(horizontalHeader);
          }
          return horizontalHeader;
       }
      

      to:

      patch
      public HorizontalHeaderTable getHorizontalHeader() throws IOException {
          HorizontalHeaderTable horizontalHeader = (HorizontalHeaderTable) tables.get(HorizontalHeaderTable.TAG);
          if (horizontalHeader != null && !horizontalHeader.getInitialized()) {
              synchronized (this) {
                  if (!horizontalHeader.getInitialized()) {
                      readTable(horizontalHeader);
                  }
              }
           }
           return horizontalHeader;
       }
      

      the lock disappears.

      Attachments

        1. 0001-PDFBOX-3080-excessive-synchronization.patch
          8 kB
          ccouturi
        2. TrueTypeFont.diff
          8 kB
          Tilman Hausherr
        3. PDFBOX-3080-sync-patch.diff
          4 kB
          Andreas Lehmkühler

        Activity

          People

            lehmi Andreas Lehmkühler
            ccouturi ccouturi
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: