I am currently developing a Web Service that has to convert PDFs to images, downscale these images and split each scale into different tiles.
For most of our users data the image sizes are not to large and the whole process fits into memory.
But especially when converting big vectorised PDFs to images, resulting in a resolution of 50k+ times 50k resolutions, one BufferedImage
instance easily hits 8GB or more in memory.
Since it is a web server and I would like to handle as many requests as possible in parallel (and even do the scaling and tiling stuff concurrently) - I need some terms of memory controlling.
I know I will probably have to store bigger images to disk between the steps. There are actually some useful open source versions of BufferedImage which can use memory and disk (see BigBufferedImage) ... but there is a performance tradeoff especially for smaller images.
90% of the time I can do everything in memory without a problem. So I would like to ask: How can one calculate the in-memory size of a BufferedImage in advance? I looked into the Javadoc and Googled around quit some time. I'm not really an expert on Image File Formats, Color Models and co. and don't know where to start. Can anybody point me out to things I need to understand to do these calculations, to what accuracy its possible and what else I need to consider?
Generally the memory required for the pixels of an image, can be computed something like (pseudo code):
Where 8.0 is the number of bits in a
byte
, andceil
rounds up to the nearest integer.For some formats, if the value isn't directly available, you may have to compute
bitsPerPixel
as follows:These will not be exact memory requirements for a
BufferedImage
, as it also contains some references to aRaster
, aColorModel
etc., but for large images, this constant will be negligible. The value computed using the formula above should be more than good enough to decide whether or not to allocate the image in memory or on disk.