我有一小段代码,每五分钟就会截取一次我的桌面截图 - 这是一个轻松思考的工作,并计算出多少截图,比如facebook ...
然而,我对它占用的内存量感到有点困惑 - 通常它会爬升到200mb的RAM,我确信这是多余的......任何人都可以告诉我一个减少内存占用的合理方法或b)它为什么涨可言?
/** * 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; } }
小智.. 14
其他答案是正确的,Java将使用尽可能多的内存,此时它将被垃圾收集.要解决此问题,可以在JVM设置中指定较小的最大堆大小.您可以使用-Xmx设置执行此操作.例如,如果您认为只需要32MB,请将其运行为:
java -Xmx32M [your main class or jar here]
您的程序堆(非堆栈内存)永远不会超过32MB,但如果它需要多于一次(并且您需要配置文件),它将崩溃.我没有看到你的程序有任何明显的泄漏(假设ImageIO不需要任何清理),所以我认为你会没事的.