Results 1 to 17 of 17
Like Tree1Likes
  • 1 Post By doWhile

Thread: How to reduce memory consumption in Java Desktop?

  1. #1
    fanjavaid is offline Member
    Join Date
    Dec 2012
    Location
    Jakarta, Indonesia
    Posts
    23
    Rep Power
    0

    Default How to reduce memory consumption in Java Desktop?

    Hello, I have an application to show a image of the user's data. Where each user has more than 1 image data.
    When I select the user in the JTable, my image data show in JPanel. The picture actually also JPanel with background image.

    My question is, memory consumption always increases, and not reduce. Sometimes the application hangs.
    How to overcome it, I am new in performance issue in Java.

    Please help,


    Thank you.

  2. #2
    Tolls is offline Moderator
    Join Date
    Apr 2009
    Posts
    11,450
    Rep Power
    18

    Default Re: How to reduce memory consumption in Java Desktop?

    If your memory increases until you get an OutOfMemoryException then you are holding onto data.
    In your case probably the images.
    Without any code it'll be hard to tell, but I would look at the code around loading and displaying images, and possibly the JPanel itself.
    Please do not ask for code as refusal often offends.

  3. #3
    fanjavaid is offline Member
    Join Date
    Dec 2012
    Location
    Jakarta, Indonesia
    Posts
    23
    Rep Power
    0

    Default Re: How to reduce memory consumption in Java Desktop?

    Quote Originally Posted by Tolls View Post
    If your memory increases until you get an OutOfMemoryException then you are holding onto data.
    In your case probably the images.
    Without any code it'll be hard to tell, but I would look at the code around loading and displaying images, and possibly the JPanel itself.
    Here is my code, method to display Images :

    Java Code:
    public void getStreamData(final PanelEntry view, final String data) {
            
            String files = null;
            String path = null;
            
            // Data is folder name that equals to user id
            if(isImages()) {
                path = "data/"+data+"/images";
            } else {
                path = "data/"+data+"/videos/thumbs";
            }
            
            File folder = new File(path);
            
            // Always remove previous image label when new data selected
            view.getPanelStream().removeAll();
            
            if (!folder.exists()) {
                JLabel label = new JLabel("No Stream Data");
                label.setForeground(Color.red);
                label.setVisible(true);
                
                // Adding to panelGallery
                view.getPanelStream().add(label);
                view.getPanelStream().revalidate();
                view.getPanelStream().repaint();
                
            } else {
                File [] listOfFiles = folder.listFiles();
    
                int maxFiles = listOfFiles.length;
                int maxView  = 15;
                            
                // Loop for get image from file
                for (int i = listOfFiles.length; i > 0 ; i--) {
                    if(listOfFiles[i].isFile()) {
                        files = listOfFiles[i].getName();
                        final String videoFiles = files;
                        
                        if(files.endsWith(".jpg") || files.endsWith(".JPG") || 
                                files.endsWith(".jpeg") || files.endsWith(".JPEG") ||
                                    files.endsWith(".png") || files.endsWith(".PNG")) {
                            final String newPath = path+"/"+files;
                            
                            try {
                                File showFile = new File(newPath);
                                ImageIcon imgSource = new ImageIcon(newPath);
                                                            
                                JPanel labelGallery = new BackgroundImageRounded(showFile);
                                labelGallery.setLayout(null);
                                labelGallery.setPreferredSize(new Dimension(160, 120));
                                labelGallery.setVisible(true);
                                
                                JLabel labelName = new JLabel(files);
                                labelName.setSize(150,15);
                                labelName.setLocation(8, 8);
                                labelName.setVisible(true);
                                labelName.setForeground(Color.ORANGE);
                                labelGallery.add(labelName);
                                
                                String videoPath = "data/"+data+"/videos/";
                                String video    = videoFiles.replace(".jpg", ".wmv");
                                String videoFile = video.replace("thumb_", "video_");
                                final String videoPlayer = videoPath+videoFile;
                                
                                if (isImages()) {
                                    labelGallery.setToolTipText("View Image");
                                } else {
                                    labelGallery.setToolTipText("Play Video");
                                    
                                    JLabel iconPlayer = new JLabel();
                                    iconPlayer.setIcon(new ImageIcon(getClass().getResource("/com/ikbiz/gastroscope/resources/player.png")));
                                    iconPlayer.setSize(61,42);
                                    iconPlayer.setVisible(true);
                                    iconPlayer.setLocation(50, 35);
                                    labelGallery.add(iconPlayer);
                                    
                                    
                                }
                                
                                labelGallery.addMouseListener(new MouseAdapter() {
                                    @Override
                                    public void mouseClicked(MouseEvent e) {        
                                        if(isImages()) {
                                            ImageViewer viewer = new ImageViewer(newPath);
                                            viewer.setVisible(true);
                                        } else {
                                            VideoViewer videoViewer = new VideoViewer();
                                            videoViewer.setViewer(videoPlayer);
                                            
                                            
                                            videoViewer.setLocationRelativeTo(null);
                                            videoViewer.pack();
                                            videoViewer.setVisible(true);
                                            
                                        }
                                    }
                                });
                                
                                // Adding to panelGallery
                                view.getPanelStream().add(labelGallery);
                                view.getPanelStream().revalidate();
                                view.getPanelStream().repaint();
                                
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }
            }
        }
    And here is my Panel :
    Java Code:
    panelStream = new GradientPanel();
    // Code of sub-components - not shown here
    // Layout setup code - not shown here
    jScrollPane4.setViewportView(panelStream);
    Thanks before :)

  4. #4
    Tolls is offline Moderator
    Join Date
    Apr 2009
    Posts
    11,450
    Rep Power
    18

    Default Re: How to reduce memory consumption in Java Desktop?

    Do you get an OutOfMemory exception when you do a simple switch between users who only have one or two images?
    That is, select user1...select user2..select user1...etc etc.
    Does it crash then?
    Or is it simply crashing when you select a user with a lot of images?
    Please do not ask for code as refusal often offends.

  5. #5
    DarrylBurke's Avatar
    DarrylBurke is offline Member
    Join Date
    Sep 2008
    Location
    Madgaon, Goa, India
    Posts
    11,189
    Rep Power
    19

    Default Re: How to reduce memory consumption in Java Desktop?

    The ImageIcon constructor that takes a String argument loads the image using java.awt.Toolkit, and Toolkit caches loaded images.

    You have two choices:
    a) flush() the image which is returned by getImage() of the ImageIcon each time the Icon is removed from the visible display.
    b) Load images using ImageIO#read(...) which doesn't perform any caching. You cannot use this with animated GIFs.

    Either of the techniques may lead to a latency in redisplaying a previously displayed image. Neither will be effective if your application genuinely requires a large number of concurrently loaded images. In that case you need to increase the memory available to the JVM with the -Xmx flag.

    db
    If you're forever cleaning cobwebs, it's time to get rid of the spiders.

  6. #6
    fanjavaid is offline Member
    Join Date
    Dec 2012
    Location
    Jakarta, Indonesia
    Posts
    23
    Rep Power
    0

    Default Re: How to reduce memory consumption in Java Desktop?

    Quote Originally Posted by Tolls View Post
    Do you get an OutOfMemory exception when you do a simple switch between users who only have one or two images?
    That is, select user1...select user2..select user1...etc etc.
    Does it crash then?
    Or is it simply crashing when you select a user with a lot of images?
    Never, because every i run this application everything works fine. But my client, try sometimes the application freeze. And must to restart it.

    I never make a profiling, because i don't know how to use profiling in my application, I just see in Task Manager. Every I select user1, user2 etc. The memory consumption increase constinuously +- 13MB, when the user have images to load it.
    Last edited by fanjavaid; 07-16-2013 at 06:11 PM.

  7. #7
    fanjavaid is offline Member
    Join Date
    Dec 2012
    Location
    Jakarta, Indonesia
    Posts
    23
    Rep Power
    0

    Default Re: How to reduce memory consumption in Java Desktop?

    Quote Originally Posted by DarrylBurke View Post
    The ImageIcon constructor that takes a String argument loads the image using java.awt.Toolkit, and Toolkit caches loaded images.

    You have two choices:
    a) flush() the image which is returned by getImage() of the ImageIcon each time the Icon is removed from the visible display.
    b) Load images using ImageIO#read(...) which doesn't perform any caching. You cannot use this with animated GIFs.

    Either of the techniques may lead to a latency in redisplaying a previously displayed image. Neither will be effective if your application genuinely requires a large number of concurrently loaded images. In that case you need to increase the memory available to the JVM with the -Xmx flag.

    db
    Thank you for your respond. Is the ImageIcon cause this problem? Because i show the images using JPanel. And use this class that already using ImageIO#read(...).

    Java Code:
    public class BackgroundImageRounded extends JPanel{
        private Image image;
    
         /** Stroke size. it is recommended to set it to 1 for better view */
        protected int strokeSize = 1;
        /** Color of shadow */
        protected Color shadowColor = Color.black;
        /** Sets if it drops shadow */
        protected boolean shady = true;
        /** Sets if it has an High Quality view */
        protected boolean highQuality = true;
        /** Double values for Horizzontal and Vertical radius of corner arcs */
        protected Dimension arcs = new Dimension(15, 15);
        /** Distance between border of shadow and border of opaque panel */
        protected int shadowGap = 5;
        /** The offset of shadow.  */
        protected int shadowOffset = 4;
        /** The transparency value of shadow. ( 0 - 255) */
        protected int shadowAlpha = 150;
        
        public BackgroundImageRounded (File file) {
            super();
            setOpaque(false);
            
            try {
                image = ImageIO.read(file);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
       
        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            int width = getWidth();
            int height = getHeight();
            int shadowGap = this.shadowGap;
            Color shadowColorA = new Color(shadowColor.getRed(), shadowColor.getGreen(), shadowColor.getBlue(), shadowAlpha);
            Graphics2D graphics = (Graphics2D) g;
    
            //Sets antialiasing if HQ.
            if (highQuality) {
                graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            }
    
            //Draws shadow borders if any.
            if (shady) {
                graphics.setColor(shadowColorA);
                graphics.fillRoundRect(
                        shadowOffset,// X position
                        shadowOffset,// Y position
                        width - strokeSize - shadowOffset, // width
                        height - strokeSize - shadowOffset, // height
                        arcs.width, arcs.height);// arc Dimension
            } else {
                shadowGap = 1;
            }
    
            //Clipping image
            Shape clipShape = graphics.getClip();
            
            if(image == null) {
                graphics.setColor(getBackground());
                graphics.fillRoundRect(0, 0, width - shadowGap, height - shadowGap, arcs.width, arcs.height);
            } else {
                RoundRectangle2D.Float rr2 =  new RoundRectangle2D.Float(0, 0, width - shadowGap, height - shadowGap, arcs.width, arcs.height);
                graphics.setClip(rr2);
                graphics.drawImage(image, 0, 0, getWidth(), getHeight(), null);
                graphics.setClip(clipShape);
            }
            
            //Draws the rounded opaque panel with borders.
            graphics.setColor(getBackground());
            //graphics.fillRoundRect(0, 0, width - shadowGap, height - shadowGap, arcs.width, arcs.height);
            //graphics.setColor(getForeground());
            graphics.setStroke(new BasicStroke(strokeSize));
            graphics.drawRoundRect(0, 0, width - shadowGap, height - shadowGap, arcs.width, arcs.height);
    
            //Sets strokes to default, is better.
            graphics.setStroke(new BasicStroke());
        }
    
    ....
    If i use -Xmx flag, can it make stable? At least the application can survive without hang.

  8. #8
    DarrylBurke's Avatar
    DarrylBurke is offline Member
    Join Date
    Sep 2008
    Location
    Madgaon, Goa, India
    Posts
    11,189
    Rep Power
    19

    Default Re: How to reduce memory consumption in Java Desktop?

    All else apart, I see two glaring inefficiencies in that code snippet.
    1) If shadowColor and shadowAlphs never change, shadowColorA should be created just once, outside of any painting method. If they do change, the setters for shadowColor and shadowAlphs should compute and create the new shadowAlpha.

    2) It's pointless to set a new stroke -- that is never made use of -- at the last line in a painting method.

    db
    If you're forever cleaning cobwebs, it's time to get rid of the spiders.

  9. #9
    doWhile is offline Moderator
    Join Date
    Jul 2010
    Location
    California
    Posts
    1,642
    Rep Power
    6

    Default Re: How to reduce memory consumption in Java Desktop?

    Never, because every i run this application everything works fine. But my client, try sometimes the application freeze. And must to restart it.
    application can survive without hang
    This does not sound like a memory management issue to me. No out of memory exception, but a freezing application (with, I presume, no exception thrown) - this sounds like a performance issue related to threading (or lackthereof). Are you loading images on the EDT, or a separate thread? Do you notice 'freezing' being dependent upon the size of the image loaded?

    I recommend posting an SSCCE that demonstrates the problem.
    DarrylBurke likes this.

  10. #10
    fanjavaid is offline Member
    Join Date
    Dec 2012
    Location
    Jakarta, Indonesia
    Posts
    23
    Rep Power
    0

    Default Re: How to reduce memory consumption in Java Desktop?

    Quote Originally Posted by DarrylBurke View Post
    All else apart, I see two glaring inefficiencies in that code snippet.
    1) If shadowColor and shadowAlphs never change, shadowColorA should be created just once, outside of any painting method. If they do change, the setters for shadowColor and shadowAlphs should compute and create the new shadowAlpha.

    2) It's pointless to set a new stroke -- that is never made use of -- at the last line in a painting method.

    db
    Yes thank you for correction i'll check again for that. But it just for effect shadow, stroke and border radius for my images.
    Not affect to performace, right?


    Quote Originally Posted by doWhile View Post
    This does not sound like a memory management issue to me. No out of memory exception, but a freezing application (with, I presume, no exception thrown) - this sounds like a performance issue related to threading (or lackthereof). Are you loading images on the EDT, or a separate thread? Do you notice 'freezing' being dependent upon the size of the image loaded?

    I recommend posting an SSCCE that demonstrates the problem.
    I loading images in separate Thread. I have two threads, first for load images and second for load images in capture modules.
    Okay may be my question to confused. I'm sorry, the point is how to remove the old images object if the next user selected? If i select user1 and then select user2, the user1's images object removed from memory.

    Thank you.

  11. #11
    doWhile is offline Moderator
    Join Date
    Jul 2010
    Location
    California
    Posts
    1,642
    Rep Power
    6

    Default Re: How to reduce memory consumption in Java Desktop?

    Quote Originally Posted by fanjavaid View Post
    I loading images in separate Thread. I have two threads, first for load images and second for load images in capture modules.
    Okay may be my question to confused. I'm sorry, the point is how to remove the old images object if the next user selected? If i select user1 and then select user2, the user1's images object removed from memory.

    Thank you.
    My point is that retaining the images in memory may not be the problem - why fix something if it ain't broke?

    Step 1: reproduce the problem. If you cannot reproduce the problem (or do not properly log the problem on the client side), then your guess is as good as ours, and my guess is that either a) you are doing work on the EDT or b) you are spawning threads which are calling non-thread safe methods which could result in all sorts of unpredictable behavior (for instance, if your getStreamData method from above is in another Thread you've got a whole slew of calls to Swing components that should be called on the EDT).

    Step 2: Pinpoint the problem and debug, either by using a debugger or reproducing it in an abbreviated form - for instance in an SSCCE. We cannot help with either of these steps, because you have yet to provide an SSCCE.

    If you don't pinpoint the problem, but rather guess, you may be spending time fixing something in which there is no need to fix.

  12. #12
    jim829 is offline Senior Member
    Join Date
    Jan 2013
    Location
    United States
    Posts
    2,931
    Rep Power
    4

    Default Re: How to reduce memory consumption in Java Desktop?

    Well, I am jumping in here late but I do have an observation. Isn't the following loop incorrect?
    Java Code:
    for (int i = listOfFiles.length; i > 0 ; i--) {
         if(listOfFiles[i].isFile()) {
            files = listOfFiles[i].getName();
    // rest of loop omitted
    ListOfFiles is an array and it seems to me you would be getting an ArrayIndexOutOfBounds exception. An array of size n is indexed from n-1 to 0. Looks to me like you're going from n to 1. Since this is a runtime exception perhaps you have not reached that code yet.

    Regards,
    Jim
    The Java™ Tutorial | SSCCE | Java Naming Conventions
    Poor planning our your part does not constitute an emergency on my part.

  13. #13
    fanjavaid is offline Member
    Join Date
    Dec 2012
    Location
    Jakarta, Indonesia
    Posts
    23
    Rep Power
    0

    Default Re: How to reduce memory consumption in Java Desktop?

    Quote Originally Posted by doWhile View Post
    My point is that retaining the images in memory may not be the problem - why fix something if it ain't broke?

    Step 1: reproduce the problem. If you cannot reproduce the problem (or do not properly log the problem on the client side), then your guess is as good as ours, and my guess is that either a) you are doing work on the EDT or b) you are spawning threads which are calling non-thread safe methods which could result in all sorts of unpredictable behavior (for instance, if your getStreamData method from above is in another Thread you've got a whole slew of calls to Swing components that should be called on the EDT).

    Step 2: Pinpoint the problem and debug, either by using a debugger or reproducing it in an abbreviated form - for instance in an SSCCE. We cannot help with either of these steps, because you have yet to provide an SSCCE.

    If you don't pinpoint the problem, but rather guess, you may be spending time fixing something in which there is no need to fix.
    Hello, thanks for advice :)
    I have new update information that the Application not freeze , but some action not called.
    I am not use EDT, i just use two thread and start it together , like this :

    Java Code:
    ...
    if (CaptureController.getNoMr() != null && CaptureController.getDataVisit() != null) {
    
                Thread loadImg = new Thread() {
                    public void run () {
                        captureController.checkDir();
    
                        captureController.getStreamData(PanelStream.getInstance());
                        captureController.getStreamDataVideos(PanelStream.getInstance());
                    }
                };
    
    
                Thread renderVideo = new Thread() {
                    public void run () {
                        try {
    
                            PanelStream.getInstance().getLblPatientDetailRecord().setText(CaptureController.getNoMr()+" ("+ CaptureController.getPatientName() +")");
    
                            CardLayout cl = (CardLayout) Application.getInstance().getContentPane().getLayout();
                            cl.show(Application.getInstance().getContentPane(), "stream");
    
                            captureController.createGraph(PanelStream.getInstance());
                        } catch (ArrayIndexOutOfBoundsException e) {
                            Message.errorMessage("Select patient first");
                        }
                    }
                };
    
                loadImg.start();
                renderVideo.start();
                
            } else {
                
                Message.errorMessage("Select data first!");
                
            }
    ...
    Is that non-thread safe?
    I'll try to use EDT.

  14. #14
    fanjavaid is offline Member
    Join Date
    Dec 2012
    Location
    Jakarta, Indonesia
    Posts
    23
    Rep Power
    0

    Default Re: How to reduce memory consumption in Java Desktop?

    Quote Originally Posted by jim829 View Post
    Well, I am jumping in here late but I do have an observation. Isn't the following loop incorrect?
    Java Code:
    for (int i = listOfFiles.length; i > 0 ; i--) {
         if(listOfFiles[i].isFile()) {
            files = listOfFiles[i].getName();
    // rest of loop omitted
    ListOfFiles is an array and it seems to me you would be getting an ArrayIndexOutOfBounds exception. An array of size n is indexed from n-1 to 0. Looks to me like you're going from n to 1. Since this is a runtime exception perhaps you have not reached that code yet.

    Regards,
    Jim
    I loop it Descending from larger number to smaller. Because my images file in filesystem use this format image_xxxxx_1.jpg, image_xxxxx_2.jpg.
    And i want loop it from 2 until 1.
    I never see ArrayIndexOutOfBoundsException, because i compare filename between that i save in Database and in the folder/filesystem.

    CMIIW

  15. #15
    DarrylBurke's Avatar
    DarrylBurke is offline Member
    Join Date
    Sep 2008
    Location
    Madgaon, Goa, India
    Posts
    11,189
    Rep Power
    19

    Default Re: How to reduce memory consumption in Java Desktop?

    Quote Originally Posted by fanjavaid View Post
    I never see ArrayIndexOutOfBoundsException
    Then that code is never executed.

    On the first iteration of the loop, i == listOfFiles.length and you try to access listOfFiles[i]. There's no way that won't throw a AIOOBE.

    db
    If you're forever cleaning cobwebs, it's time to get rid of the spiders.

  16. #16
    jim829 is offline Senior Member
    Join Date
    Jan 2013
    Location
    United States
    Posts
    2,931
    Rep Power
    4

    Default Re: How to reduce memory consumption in Java Desktop?

    But he could be ignoring it by catching an eating the exception somewhere up the call stack.

    Regards,
    Jim
    The Java™ Tutorial | SSCCE | Java Naming Conventions
    Poor planning our your part does not constitute an emergency on my part.

  17. #17
    DarrylBurke's Avatar
    DarrylBurke is offline Member
    Join Date
    Sep 2008
    Location
    Madgaon, Goa, India
    Posts
    11,189
    Rep Power
    19

    Default Re: How to reduce memory consumption in Java Desktop?

    Didn't think of that.

    db
    If you're forever cleaning cobwebs, it's time to get rid of the spiders.

Similar Threads

  1. Replies: 2
    Last Post: 08-20-2012, 06:38 PM
  2. Reduce desktop application memory
    By major in forum Advanced Java
    Replies: 8
    Last Post: 06-26-2011, 11:54 AM
  3. how to record maximum heap memory consumption
    By pvh35 in forum Advanced Java
    Replies: 2
    Last Post: 01-17-2011, 05:23 PM
  4. How to reduce the size or avoiding out of memory error?
    By rajeshkumarmsc in forum Advanced Java
    Replies: 3
    Last Post: 08-11-2007, 10:15 PM
  5. Consumption of memory
    By Daniel in forum Advanced Java
    Replies: 1
    Last Post: 07-06-2007, 09:11 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •