有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java在使用ExecutorService时如何管理内存?

我有大量的任务需要使用multithreading执行

我使用ExecutorService提交大量Callable objects,每个Callable object包含一些执行所需的resource

问题

这些任务太多,以至于提交给ExecutorServiceCallable objects占用了太多内存,然后heap就耗尽了

我想知道JVM什么时候为这些Callable objects释放空间

它是否在任务完成后立即执行此操作?我如何管理用于ExecutorService的内存

我想控制对ExecutorService的提交,例如,当内存不足时,阻止提交,直到完成一些任务并释放空间。可以吗


整个代码太复杂了,我会附上我的代码的主要框架

public class MyCallable implements Callable<Result> {

  ... // Some members

  public MyCallable(...) {
    ...
  }

  @Override
  public Result call() throws Exception {
    ... // Doing the task
  }
}

class MyFutureTask extends FutureTask<Result> {

  ... // Some members

  public MyFutureTask(...) {
    super(new MyCallable(...));
  }

  @Override
  public void done() {
    Result result = get();
    ... // Something to do immediately after the task is done
  }
}

// Here is the code to add tasks
ExecutorService executor = Executors.newFixedThreadPool(threadPoolSize);
while (...) {
  ... // Reading some data from files
  executor.submit(new MatchFutureTask(...));
}
executor.shutdown();

共 (3) 个答案

  1. # 1 楼答案

    似乎使用遗嘱执行人。newCachedThreadPool()将内存减少了30%-60%

  2. # 2 楼答案

    方法Runtime.getRuntime().freeMemory()将告诉您JVM有多少可用内存。您可以编写一个ThreadFactory实现,在创建新线程之前检查该值

  3. # 3 楼答案

    如果您使用的是ExecutorService,那么您必须向构造函数传递一个BlockingQueue,对吗?我假设您正在使用ThreadPoolExecutor。使用具有固定容量的ArrayBlockingQueue,并传递ThreadPoolExecutor。调用ThreadPoolExecutor构造函数的CallerRunPolicy。如果您将maximumPoolSize设置为某个合理的值,这将相当有效地限制您的提交速率

    为了回答您的第一个问题,VM将在不再引用对象之后的某个时间释放内存。如果可调用项在状态方面是自包含的,那么一旦它完成执行,VM应该在给您一个内存不足错误之前对其进行垃圾收集