Needed RAM to display images in java - java

Another conceptual question..
I am fighting against a java heap space exception.
My problem is, that i have to render/display small but a lot of images.
I exceed maximal ram. (edit vm options does not help) Yet i store all images in one List.
I think about if it may need less ram if i render the images one by one and store it temporary on local hard disk.
Will the images be still all in ram if displayed on screen?
Changes in the code would be significant so i want to ask this before..

If your use case is lots of images/icons in a JList/JTable inside a JScrollPane, I once wrote something similar for a CMS search result display:
I had thumbnails of larger images stored on server/cached on disk. You can exploit the fact that the JList/JTable (or Swing components in general) will only try to paint the components visible on screen, so you don't need to track this yourself. I used a JLabel with ImageIcon as renderer in the list, and a fixed size cache of icons in memory. Whenever the renderer hit an image not in cache, I used a lazy-loading technique with a placeholder icon returned immediately, while loading the icon in the background using a SwingWorker. When loaded, the SwingWorker issued a repaint to JList. The icon would now be in cache, and the list would paint nicely.
Some bonus tips: Make sure your icon cache is larger than the maximum number of items that can be displayed on screen. Also, use a limited (fixed size) thread pool for your SwingWorkers (possibly loading multiple icons at once), to avoid exessive reapint-loops that may cause flickering.

Related

Implementation of specfical region refresh with Java Swing

The number of models that my swing application needs to display is currently 2000 to 10000 images. After multiple zooming or using for a period of time, the memory continues to increase and will not decrease,How can I optimize it?
It is hard to recommend anything without knowing more about the environment, but I'll list some general tips:
You resize images every time you zoom in/out. This creates new images rapidly, especially if you zoom in using the mouse wheel or some other tool that fires events rapidly. Consider creating the image after the resizing has finished.
Don't hold references to unused images. This means you shouldn't store all the resized images, only the used ones.
Probably you don't need every image in every state of the
application - consider creating a loading screen which is shown while your application loads and resizes the used images, and discards the previous ones. (It does not have to be an actual loading screen or animation)
I've never seen a small or medium-scale project which needed 10k unrelated images. You might be storing animations per-frame, which is way less efficient than using video formats.
If you have many similar images, consider not loading them from file but instead paint them dynamically (you have a base image and paint over it using the component's Graphics).
Call the garbage collector. This should free up any unused space in the memory.

drawing complex generated image in java 2d

I have a very large complicated diagram that needs to be drawn on the fly.
I am already using a double buffered technique to paint the image (from this answer: Using threads to paint panel in java) however, the generated image that is being painted is so large that it cant be painted as a single image (and the multiple images required to paint it cant be stored in memory all at the same time). For this reason, I paint the currently visible area of the view + some margin. As I scroll, I paint the area that is going to come next, and remove from memory the area we just came from. However, if the user then decides to change direction, they need to wait for this area to be painted again. My question is this:
If a single "frame" of the screen being painted is approximately 1000*1000 pixels, in which approximately 5000 lines/circles are drawn (nodes/edges of a graph) is it likely to be more efficient to repaint this image each time, or is there a way to affectively cache the image to hard disk (to avoid java heap limitations).
Ive already optimised the paint method as much as I can think of, but there are still several seconds of delay if a user scrolls to quickly (i.e. moves out of the painted area before the next set of "frames" are painted). So my second question is this: Will moving to OpenGL offer a large improvement, and will it require major changes to the infrastructure of the code? (I tried doing this a couple of days ago, and found it was not as simple as I thought - often led to the computer crashing).
Several things come to mind:
Profile to verify your working hypotheses; self-time the animation budget on your target platform for comparison, as shown in this AnimationTest.
Compare your approach to the example cited here; it scales into the 1000's and accommodates dragging selections into the hundreds.
If your frames have a suitable geometry, consider adopting the flyweight pattern for rendering; JTable rendering is an example; the underlying mechanism using CellRendererPane is examined here.

Heap overflow implementing Undo in Swing App

I am developing a scribble type app in java swing. It is in a rudimentary stage and is shown here.
I have implemented the undo feature which undoes the last drawn stroke upto. The undo feature can be done upto a maximum defined undo levels.
The undo feature works by copying the contents of the drawing canvas after each stroke in an Image array.
This array acts like a First-In-Last-Out Stack. When undo is clicked the stack is poped
and the obtained image is drawn on screen.
Now the problem I am facing is, the current method of implementation of undo takes up too much memory. At undo levels of 20, almost 70-80 MB of memory is used up, and at levels of 30, heap overflow occurs.
Is there a better way of implementing the undo feature ? Thanks.
EDIT : I found some useful information here which may be helpful.
You need to represent the steps in your drawing differently. In the current approach you are using, you save the Canvas each time anew as an uncompressed picture - and that is memory-greedy.
Try to refactor your code so that only the strokes being drawn on the Canvas are saved into the stack. This will put a little bit more overhead when rendering the picture (you would need to redraw the entire canvas each time a change occurs), but Java is designed to deal with that.
Having saved only shapes, the memory requirements should decrease significantly. Use the Shape class to represent the strokes on the canvas.

Which is better to use, JTabbedPane or JInternalFrame?

I have a java based tool that displays every new canvas image in a new tab, and am planing to improve it with more functions. And soon its gona become complex tool have options to create images, viewing sequence images, thus having thought of using JInternal frame rather than JTabbedPane. So would like to know which would be better option in terms of efficiency,processing power and memory?
I think it depends a lot of the size of the images and the way you actually want to display the images to users.
If you have very big images like 10+ of MPixels ones or your users don't need to see several images in the same time then you could go with the JTabbedPane. When you display only one image at a time, you can improve memory consumption by having only that image loaded into memory and probably keep the other images wrapped in SoftReference.
I'd go with JInternalFrame, illustrated here, as each frame can be resized individually. JTabbedPane, shown here, has a lot of appeal, but one-size-may-not-fit-all without scrolling. Only profiling such examples can realistically address efficiency, processing power and memory.

Quickly load part of image in java

I'm currently working in a map editor for a 2D, tile based game. When I create a new map, the tileset is loaded into memory and displayed in a JPanel that's inside a JScrollPane, so I can choose the tiles I wish to draw.
At first, I was just drawing the full image, but that made scrolling pretty slow, so now I only draw the visible portion of it and that works just fine. What I'm worried about is the memory usage, because the tileset is pretty big. I'm not getting any OutOfMemory erros, but I would like to optimise everything I can.
I tried using ImageReader together with ImageReadParam.setSourceRegion(); and that uses a lot less memory, but the scrolling becomes slower and the image blinks like crazy when scrolling - probably because it takes some time to read the image form disk.
So, is there a good way to quickly load parts of a big image without fully loading it? Or maybe there's a way to fully load it but in a compressed manner?

Categories