ccouturi created PDFBOX-3080:
--------------------------------
Summary: TrueTypeFont synchronization
Key: PDFBOX-3080
URL: https://issues.apache.org/jira/browse/PDFBOX-3080
Project: PDFBox
Issue Type: Improvement
Components: FontBox
Affects Versions: 2.0.0
Environment: 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)
Reporter: ccouturi
Priority: Minor
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:
public synchronized HorizontalHeaderTable getHorizontalHeader() throws
IOException {
HorizontalHeaderTable horizontalHeader = (HorizontalHeaderTable)tables.get(
HorizontalHeaderTable.TAG );
if (horizontalHeader != null && !horizontalHeader.getInitialized()) {
readTable(horizontalHeader);
}
return horizontalHeader;
}
to:
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.
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]