当然,我知道Java程序占用了相当多的内存并且不愿意放弃它,但是我仍然想了解这种构建程序工作(对于小程序)的方案是否是最优的,因为在Windows 任务管理器向我显示与该程序关联的相应 Java 进程占用了半 GB 之多。
我假设(仅此而已,你是这里的大师) while 循环内发生的事情是在每个循环中重新创建的,因此应该在循环完成时使用(作为不必要的东西),但似乎这不是正在发生。
我知道垃圾收集器本身知道何时以及做什么,但我想了解 - 我的假设是否正确,或者这样的方案(如我所示)不一定有助于内存的经济使用?
// an approximate simplified diagram of how the program core works
while (true) {
try {
Thread.sleep(timeToWaite);
} catch (InterruptedException e) {}
final WebDriver driver = ServerUtils.getWebDriver();
try {
// the biggest work using webdriver happens here
} catch (Exception e) {...}
driver.quit(); // closes all the browser windows and terminates the WebDriver session
// clean the tails if any remain
Thread brokerThread = new Thread(new ProcessFinisher());
brokerThread.setDaemon(false);
brokerThread.start();
try {
brokerThread.join();
} catch (InterruptedException e) {}
}
我假设(仅此而已,你是这里的大师) while 循环内发生的事情是在每个循环中重新创建的,因此应该在循环完成时使用(作为不必要的东西),但似乎这不是正在发生。
Java GC 不一定会在对象变得不可访问时立即收集它们。 如果没有内存压力,它不一定会收集它们。
我知道垃圾收集器本身知道何时以及做什么,但我想了解 - 我的假设是否正确,或者这样的方案(如我所示)不一定有助于内存的经济使用?
我觉得你太努力了。 GC 的要点是您不必(太多)担心管理内存,但这正是您似乎正在尝试做的事情。 通过避免保留对不再需要的对象的引用来与 GC 配合。 通常没有必要清除对象引用或关闭您很快要重新创建/重新启动的服务。
当你说:
与该程序关联的相应 Java 进程占用多达半千兆字节。
...您区分 Java 进程和其中运行的程序是正确的。 就操作系统而言,JVM 是它管理的进程。 该进程在启动时从操作系统获取的内存可能比运行程序实际需要的内存多。 在某些情况下,它还可能从操作系统获取额外的内存,而不是执行昂贵的完整 GC。
如果您使用的是 Oracle 或 OpenJDK JVM,那么它具有控制初始 (
-Xms
) 和最大 (-Xmx
) 堆大小的命令行选项。 您可能会对程序实际需要多少内存感到惊讶,但是一旦确定了这一点,就可以使用这些选项(尤其是后者)来防止 JVM 使用超出其需要的内存。 但请注意,将最大值设置得太小会导致 OutOfMemoryError
,而留下太小的净空可能会导致性能问题。