Skip to main content

JVM Hangs after creating planar image

7 replies [Last post]
vaibhavvj
Offline
Joined: 2008-12-02

Hi,
Our weblogic 8.1 JVM hangs because of a deadlock after processing some jpeg images using JAI. We were using JAI 1.1.2 and shifted to 1.1.3, but the problem still persists. The images are processed under our application server(Weblogic 8.1).

This is how we are creating the planar image.
PlanarImage objPlanarImage = null;
RenderedImage src = null;
src = JAI.create("stream", SeekableStream.wrapInputStream(bais, false));
objPlanarImage = PlanarImage.wrapRenderedImage(src);

Here's the stack trace. Any solution to this will be very helpful.

"Thread-12" id=185 idx=0xc0 tid=24273 prio=5 alive, daemon
at java/awt/image/SinglePixelPackedSampleModel.getPixels(IIII[ILjava/awt/image/DataBuffer;)[I(SinglePixelPackedSampleModel.java:476)[optimized]
at java/awt/image/Raster.getPixels(IIII[I)[I(Raster.java:1552)[optimized]
at java/awt/image/WritableRaster.setRect(IILjava/awt/image/Raster;)V(WritableRaster.java:446)[optimized]
at sun/awt/image/SunWritableRaster.setRect(IILjava/awt/image/Raster;)V(SunWritableRaster.java:112)[inlined]
at sun/awt/image/ByteInterleavedRaster.setRect(IILjava/awt/image/Raster;)V(ByteInterleavedRaster.java:1133)[optimized]
at java/awt/image/WritableRaster.setRect(Ljava/awt/image/Raster;)V(WritableRaster.java:385)[optimized]
at sun/awt/image/SunWritableRaster.setRect(Ljava/awt/image/Raster;)V(SunWritableRaster.java:107)
at com/sun/media/jai/codecimpl/JPEGImage.(Ljava/io/InputStream;Lcom/sun/media/jai/codec/ImageDecodeParam;)V(JPEGImageDecoder.java:152)
at com/sun/media/jai/codecimpl/JPEGImageDecoder.decodeAsRenderedImage(I)Ljava/awt/image/RenderedImage;(JPEGImageDecoder.java:53)
at com/sun/media/jai/opimage/CodecRIFUtil.create(Ljava/lang/String;Ljava/awt/image/renderable/ParameterBlock;Ljava/awt/RenderingHints;)Ljava/awt/image/RenderedImage;(CodecRIFUtil.java:96)
at com/sun/media/jai/opimage/JPEGRIF.create(Ljava/awt/image/renderable/ParameterBlock;Ljava/awt/RenderingHints;)Ljava/awt/image/RenderedImage;(JPEGRIF.java:52)
at jrockit/reflect/CompiledMethodInvoker.invoke0(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;(Unknown Source)
at jrockit/reflect/CompiledMethodInvoker.invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;(Unknown Source)
at java/lang/reflect/Method.invoke(Ljava/lang/Object;[Ljava/lang/Object;I)Ljava/lang/Object;(Unknown Source)
at javax/media/jai/FactoryCache.invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;(FactoryCache.java:130)
at javax/media/jai/OperationRegistry.invokeFactory(Ljava/lang/String;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/Object;(OperationRegistry.java:1682)
at javax/media/jai/ThreadSafeOperationRegistry.invokeFactory(Ljava/lang/String;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/Object;(ThreadSafeOperationRegistry.java:481)
at javax/media/jai/registry/RIFRegistry.create(Ljavax/media/jai/OperationRegistry;Ljava/lang/String;Ljava/awt/image/renderable/ParameterBlock;Ljava/awt/RenderingHints;)Ljava/awt/image/RenderedImage;(RIFRegistry.java:340)
at com/sun/media/jai/opimage/StreamRIF.create(Ljava/awt/image/renderable/ParameterBlock;Ljava/awt/RenderingHints;)Ljava/awt/image/RenderedImage;(StreamRIF.java:110)
at jrockit/reflect/CompiledMethodInvoker.invoke0(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;(Unknown Source)
at jrockit/reflect/CompiledMethodInvoker.invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;(Unknown Source)
at java/lang/reflect/Method.invoke(Ljava/lang/Object;[Ljava/lang/Object;I)Ljava/lang/Object;(Unknown Source)
at javax/media/jai/FactoryCache.invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;(FactoryCache.java:130)
at javax/media/jai/OperationRegistry.invokeFactory(Ljava/lang/String;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/Object;(OperationRegistry.java:1682)
at javax/media/jai/ThreadSafeOperationRegistry.invokeFactory(Ljava/lang/String;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/Object;(ThreadSafeOperationRegistry.java:481)
at javax/media/jai/registry/RIFRegistry.create(Ljavax/media/jai/OperationRegistry;Ljava/lang/String;Ljava/awt/image/renderable/ParameterBlock;Ljava/awt/RenderingHints;)Ljava/awt/image/RenderedImage;(RIFRegistry.java:340)
at javax/media/jai/RenderedOp.createInstance(Z)Ljavax/media/jai/PlanarImage;(RenderedOp.java:830)
^-- Holding lock: javax/media/jai/RenderedOp@0xb045040[recursive]
at javax/media/jai/RenderedOp.createRendering()V(RenderedOp.java:878)
^-- Holding lock: javax/media/jai/RenderedOp@0xb045040[thin lock]
at javax/media/jai/RenderedOp.getWidth()I(RenderedOp.java:2190)
at com/wellsfargo/bir/rh/BIRHandler.jaiOperatedImage([B)[B(BIRHandler.java:2837)
at com/wellsfargo/bir/rh/BIRHandler.createPDFDocument(J)V(BIRHandler.java:2303)
at com/wellsfargo/bir/rh/BIRHandler.processRequest(IJ)V(BIRHandler.java:249)
at com/wellsfargo/bir/task/BIRGeneratePDFTask.task()V(BIRGeneratePDFTask.java:199)
at com/wellsfargo/bir/util/EventHandler.run()V(EventHandler.java:130)
at java/util/TimerThread.mainLoop()V(Timer.java:432)
at java/util/TimerThread.run()V(Timer.java:382)
at jrockit/vm/RNI.c2java(IIII)V(Native Method)
-- end of trace

Blocked lock chains
===================
Chain 2:
"ExecuteThread: '1' for queue: 'weblogic.socket.Muxer'" id=49 idx=0x68 tid=23276 waiting for java/lang/String@0x8f2c728 held by:
"ExecuteThread: '2' for queue: 'weblogic.socket.Muxer'" id=50 idx=0x6a tid=23277 in chain 1

Open lock chains
================
Chain 1:
"ExecuteThread: '0' for queue: 'weblogic.socket.Muxer'" id=48 idx=0x66 tid=23275 waiting for java/lang/String@0x8f2c728 held by:
"ExecuteThread: '2' for queue: 'weblogic.socket.Muxer'" id=50 idx=0x6a tid=23277 (active)

===== END OF THREAD DUMP ===============

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
jonasfleer
Offline
Joined: 2007-11-21

I don't see that you give a RenderingHints instance to the JAI.create method, so i assume that it uses the default one. If you do multi-threaded server-side image processing this can cause the threads blocking each other as they all use the same SunTileCache (which has some synchronized blocks).

So, try to create a new renderinghints instance for each incoming request.

HTH

Jonas

vaibhavvj
Offline
Joined: 2008-12-02

Thanks Jonas for the suggestion.
Can you please give me an example about how i need to use RenderingHints ?

vaibhavvj
Offline
Joined: 2008-12-02

Hi Jonas,
This is how i used Rendering Hints.

PlanarImage objPlanarImage = null;
RenderedImage src = null;
RenderingHints hints = new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
src = JAI.create("stream", SeekableStream.wrapInputStream(bais, false), hints);
objPlanarImage = PlanarImage.wrapRenderedImage(src);

And i have the following exception.
java.lang.IllegalArgumentException: Stream - Parameter value`s class (java.awt.RenderingHints) is not an instance of the parameter class (com.sun.media.jai.codec.ImageDecodeParam) for parameter "param".
at javax.media.jai.JAI.createNS(Unknown Source)
at javax.media.jai.JAI.create(Unknown Source)
at javax.media.jai.JAI.create(Unknown Source)

Can you please tell me what should be the key/value pair ?

jonasfleer
Offline
Joined: 2007-11-21

I have created a RenderingHintsFactory class:

/**
* Memory capacity of tile cache per operator in bytes.
*/
private static final long TILE_CACHE_MEMORY_CAPACITY = 64*1024*1024L; // 64 megabytes;

static {
DEFAULT_RENDERING_HINTS.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
DEFAULT_RENDERING_HINTS.put(JAI.KEY_INTERPOLATION, Interpolation.getInstance(Interpolation.INTERP_BICUBIC));
// .... more hints set to the default values, look into RenderingHints and JAI class what are possible keys here
}

/**
* @return A newly created RenderingHints instance with the hints set
* to default values. Included is also a new {@link TileCache} instance,
* to avoid thread-locking (this happens if all threads share the same
* {@link TileCache}.
*/
public static RenderingHints createDefaultRenderingHintsInstance() {
RenderingHints retval = (RenderingHints)DEFAULT_RENDERING_HINTS.clone();

// Create a separate tile cache for this particular instance
TileCache tileCache = JAI.createTileCache();
tileCache.setMemoryCapacity(TILE_CACHE_MEMORY_CAPACITY);
retval.put(JAI.KEY_TILE_CACHE, tileCache);

return retval;
}

/**
* Return the rendering hints after it isn't needed anymore.
* This gives the ability to clean things up or to re-use the instance.
* @param returnedRenderingHints
*/
public static void releaseRenderingHints(RenderingHints returnedRenderingHints) {
((TileCache)returnedRenderingHints.get(JAI.KEY_TILE_CACHE)).flush();
}

So DEFAULT_RENDERING_HINTS is a static template for all rendering hints instances, which is cloned for each new request. The standard size for the tile cache is 16MB, we have set it to 64MB, which is enough for our images.
On the end of each request the renderinghints instance is returned to the factory for clean up.

vaibhavvj
Offline
Joined: 2008-12-02

Thanks Jonas.

adam21977
Offline
Joined: 2009-05-01

it still hangs for me .. is this thread safe ?
can you post the Factory class and the usage ? Thanks
I am looking to build an image servlet as follows
RenderingHints hints =

RenderingHintsFactory.createDefaultRenderingHintsInstance();

// Loads the image from the given path and filename
PlanarImage img = null;
try {

RenderedImage src = null;

src = JAI.create("url", url, hints);
img = PlanarImage.wrapRenderedImage(src);

//img = (PlanarImage) JAI.create("stream", url, hints);
} catch (Exception e) {
e.printStackTrace();
} finally {
//RenderingHintsFactory.releaseRenderingHints(hints);
System.out.println("imgae bytes loaded" + url.getPath());
}

Message was edited by: adam21977

jyotigupta.iitd
Offline
Joined: 2012-02-02

Hi,

I am facing a similar problem of threads getting stuck . I have tried the above suggested method of using RenderingHints. Were you able to resolve the problem?

thanks.