1

I am constantly getting images from a local server and I want to show them on the JPanel.

I wrote a code that works for a while without any issue. But after some time (approximately 5 min), I get this error:

Exception in thread "Thread-0" java.lang.InternalError: a fault occurred in an unsafe memory access operation

at com.sun.imageio.plugins.jpeg.JPEGImageReader.readImage(Native Method)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.readInternal(JPEGImageR$
at com.sun.imageio.plugins.jpeg.JPEGImageReader.read(JPEGImageReader.ja$
at SICK.DisplayImage.updatePane(DisplayImage.java:225)
at SICK.DisplayImage.access$000(DisplayImage.java:35)
at SICK.DisplayImage$1.run(DisplayImage.java:356)
at java.lang.Thread.run(Thread.java:748)

This is where I read images from the server:

private BufferedImage updatePane(JLabel label) {

        try {
            InputStream input = new URL("http://192.168.250.21:8080/NewImage.jpg").openStream();
            
            ImageInputStream stream = ImageIO.createImageInputStream(input);
            
            ImageReader reader = ImageIO.getImageReaders(stream).next(); 

            reader.setInput(stream);

            int width = reader.getWidth(0);
            int height = reader.getHeight(0);
            ImageTypeSpecifier spec = reader.getImageTypes(0).next(); 

            BufferedImage image = MappedImageFactory.createCompatibleMappedImage(width, height, spec);
                    
            ImageReadParam param = reader.getDefaultReadParam();
            param.setDestination(image);

            image = reader.read(0, param);
            
            stream.close();
            input.close();

            initialize(image, label);
            return image;
        } catch (MalformedURLException e) {
            
            e.printStackTrace();
        } catch (IOException e) {
            
            e.printStackTrace();
        }
        return null;
    }

This is the initialize function where I add the images and the JLabel to the JPanel:

private void initialize(BufferedImage image, JLabel label) {
        GridBagConstraints c =  new GridBagConstraints(0,0,1,1,0,0, GridBagConstraints.NORTHWEST, GridBagConstraints.NORTHWEST, 
                    new Insets(0, 0, 0, 0), 0, 0);
                        
        JLabel imgLabel = new JLabel(new ImageIcon(image));
            
        int placeInY = 0;
        
        c.fill = GridBagConstraints.BOTH;
        c.weightx = 0;
        c.weighty = 0;
        c.gridx = 0;
        c.gridy = placeInY++;
        c.gridheight = 1;
        c.gridwidth = 8;
        pane.add(imgLabel, c);
            
        c.fill = GridBagConstraints.BOTH;
        c.weightx = 0;
        c.weighty = 0;
        c.gridx = 2;
        c.gridy = placeInY++;
        c.gridheight = 1;
        c.gridwidth = 1;
        pane.add(label, c);
        
        this.add(pane);
    }

And this is my main function:

public static void main(String[] args) {
        final DisplayImage page = new DisplayImage();

        final Thread t1 = new Thread(new Runnable() {
            
            public void run() {
                while(true) {
                
                    try {
                        TimeUnit.MILLISECONDS.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    page.removeAll();
                    page.updatePane(new JLabel("New Image"));
                    page.validate();
                    page.repaint();
                }
            }
        });
        
        SwingUtilities.invokeLater(new Runnable() {
            
            public void run() {
                t1.start();
            }
        });
    }

The error occurs in the line image = reader.read(0, param);

I checked out this error message and it is said that there are a couple of reasons this error to occur.

One of them is that the source of the images may be invalid but I checked and the server keeps providing the images.

One of them is that the RAM may be out of memory (memory leakage). I don't know for sure but this seems more like it.

If this error is caused by memory leakage, how do I solve it?

Note: I am using this code for streaming images: https://github.com/haraldk/TwelveMonkeys/blob/master/sandbox/sandbox-common/src/main/java/com/twelvemonkeys/image/MappedImageFactory.java

EDIT: I am having this issue in my linux system which has 512 MB of RAM. I tried to get this error on my PC which has 16 GB of RAM but the error didn't occur even though I have waited for 45 minutes.

I have monitored the JVM for 45 minutes with VisualVM. Here is the heap and metaspace:

Heap

Metaspace

Heap didn't increase but metaspace kept increasing. I am still watching and it is still increasing. But the metaspace size increases automatically too.

As I have read here, the metaspace size increases automatically, if it is needed. But in my opinion; if there is no unused RAM left to increase the size, it could cause a memory leakage error. As I have mentioned above, I am getting this error on my Linux system which has 512 MB of RAM.

I reckon, I have to wait so freakishly much more for this error to occur on my PC of 16 GB of RAM.

Do you think I am right about the memory leakage? If so, how do I solve it?

EDIT 2: I have checked the memory usage of the JVM in my Linux System. Here are the results of them after getting the error:

>sudo jcmd 1955 GC.heap_info
Java HotSpot(TM) Client VM warning: Insufficient space for shared memory file:
2616
Try using the -Djava.io.tmpdir= option to select an alternate temp location.

1955:
 def new generation   total 2560K, used 747K [0xac200000, 0xac4c0000, 0xaec00000)
  eden space 2304K,  32% used [0xac200000, 0xac2baf78, 0xac440000)
  from space 256K,   0% used [0xac440000, 0xac440000, 0xac480000)
  to   space 256K,   0% used [0xac480000, 0xac480000, 0xac4c0000)
 tenured generation   total 5504K, used 5210K [0xaec00000, 0xaf160000, 0xb4000000)
   the space 5504K,  94% used [0xaec00000, 0xaf1169d8, 0xaf116a00, 0xaf160000)
 Metaspace       used 7798K, capacity 7957K, committed 8088K, reserved 8496K

I couldn't lower my metaspace size under 10 MB because it instantly gave the out of memory error below. So I lowered my Metaspace to 13 MB and heap size to 40MB on my PC with the command:

java -jar -XX:MaxMetaspaceSize=13m -Xmx40m --illegal-access=warn gui.for.linux-0.0.1-SNAPSHOT.jar

But when metaspace was full, I got this error:

Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread "StreamCloser"

So I couldn't reproduce the error that I am getting on the Linux system by lowering heap and metaspace size on my PC.

But metaspace of JVM in Linux system is 94% used after it gives an error.

I couldn't figure out what is causing the error to occur.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Mehmet
  • 118
  • 7
  • [The first answer to this question](https://stackoverflow.com/questions/45536049/java-lang-internalerror-a-fault-occurred-in-a-recent-unsafe-memory-access-opera) talks about this kind of `InternalError`. From what I read there code be a wide array of reasons for this. – Joachim Sauer Aug 16 '21 at 08:35
  • @JoachimSauer I have read that answer too. I am sorry If I sounded as I am saying there can only be 2 reasons for this error. But I just wanted to point out the ones I am suspecting for the cause of this error. – Mehmet Aug 16 '21 at 08:42
  • 2
    It is possible that memory is the issue, but you'll have to monitor your application to be sure. – Hulk Aug 16 '21 at 08:55
  • @Hulk I have edited and added JVM monitoring images. Could you check that out? – Mehmet Aug 16 '21 at 11:52
  • 1
    Since this is happening in the image reading code, can you reproduce it with a fixed image, maybe loading it from disk instead? – Didier L Aug 16 '21 at 12:08
  • @Mehmet you can configure the heap size available to your JVM, may be worth trying a similar configuration than the one in your production environment. (how exactly the configuration works depends on the JVM implementation and version you are using). – Hulk Aug 16 '21 at 12:08
  • @Hulk I have lowered the JVM memory as you said. Could you check the EDIT 2 in the question? – Mehmet Aug 17 '21 at 09:14

1 Answers1

0

Answer of Vyacheslav in this post explains why metaspace increases.

I run the application with -Djava.compiler=NONE option and there was no increase in the metaspace.

Metaspace

Mehmet
  • 118
  • 7