Why is this Java program taking up so much memory?

I have a small piece of code that takes a screenshot of my desktop every five minutes. However, I am a little confused by the amount of memory that it occupies - often it creeps up to 200 MB of RAM, which, I am sure, is excessive ... Can someone tell me a) reasonable ways to reduce the amount of memory or b) why does it go up ?

/** * Code modified from code given in http://whileonefork.blogspot.co.uk/2011/02/java-multi-monitor-screenshots.html following a SE question at * http://stackoverflow.com/questions/10042086/screen-capture-in-java-not-capturing-whole-screen and then modified by a code review at http://codereview.stackexchange.com/questions/10783/java-screengrab */ package com.tmc.personal; import java.awt.AWTException; import java.awt.GraphicsDevice; import java.awt.GraphicsEnvironment; import java.awt.Rectangle; import java.awt.Robot; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; import java.util.TimeZone; import java.util.concurrent.TimeUnit; import javax.imageio.ImageIO; class ScreenCapture { static int minsBetweenScreenshots = 5; public static void main(String args[]) { int indexOfPicture = 1000;// should be only used for naming file... while (true) { takeScreenshot("ScreenCapture" + indexOfPicture++); try { TimeUnit.MINUTES.sleep(minsBetweenScreenshots); } catch (Exception e) { e.printStackTrace(); } } } //from http://www.coderanch.com/t/409980/java/java/append-file-timestamp private final static String getDateTime() { DateFormat df = new SimpleDateFormat("yyyy-MM-dd_hh:mm:ss"); df.setTimeZone(TimeZone.getTimeZone("PST")); return df.format(new Date()); } public static void takeScreenshot(String filename) { Rectangle allScreenBounds = getAllScreenBounds(); Robot robot; try { robot = new Robot(); BufferedImage screenShot = robot.createScreenCapture(allScreenBounds); ImageIO.write(screenShot, "jpg", new File(filename + getDateTime()+ ".jpg")); } catch (AWTException e) { System.err.println("Something went wrong starting the robot"); e.printStackTrace(); } catch (IOException e) { System.err.println("Something went wrong writing files"); e.printStackTrace(); } } /** * Okay so all we have to do here is find the screen with the lowest x, the * screen with the lowest y, the screen with the higtest value of X+ width * and the screen with the highest value of Y+height * * @return A rectangle that covers the all screens that might be nearby... */ private static Rectangle getAllScreenBounds() { Rectangle allScreenBounds = new Rectangle(); GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); GraphicsDevice[] screens = ge.getScreenDevices(); int farx = 0; int fary = 0; for (GraphicsDevice screen : screens) { Rectangle screenBounds = screen.getDefaultConfiguration().getBounds(); // finding the one corner if (allScreenBounds.x > screenBounds.x) { allScreenBounds.x = screenBounds.x; } if (allScreenBounds.y > screenBounds.y) { allScreenBounds.y = screenBounds.y; } // finding the other corner if (farx < (screenBounds.x + screenBounds.width)) { farx = screenBounds.x + screenBounds.width; } if (fary < (screenBounds.y + screenBounds.height)) { fary = screenBounds.y + screenBounds.height; } allScreenBounds.width = farx - allScreenBounds.x; allScreenBounds.height = fary - allScreenBounds.y; } return allScreenBounds; } } 
+8
source share
3 answers

The other answers are correct that Java will use as much memory as it is allowed, and at this point it will collect garbage. To get around this, you can specify a smaller heap size in the JVM settings. You do this with the -Xmx setting. For example, if you think you only need 32 MB, run it as:

 java -Xmx32M [your main class or jar here] 

The heap of your program (non-stack memory) will never take more than 32 MB, but it will crash if it needs more than immediately (and where you need to profile). I do not see any obvious leaks in your program (assuming ImageIO does not require any cleaning), so I think that everything will be fine.

+13
source

For a modern computer, 200 MB is not excessive memory. The JVM will allow the heap to grow for a while if you create and discard many objects so that your program does not get caught up in garbage collection. Let your program run for several hours and then check if you think there is a problem.

+3
source

The JVM garbage collector will eventually clear your heap of memory. To manually delete this heap call Runtime.getRuntime().gc(); but I do not recommend doing this every 5 minutes.

+1
source

Source: https://habr.com/ru/post/959493/


All Articles