java - Java中的多线程垃圾收集: Sharing object outside prevents GC?

标签 java multithreading garbage-collection

考虑以下方法:

public void Parse(String[] S, Objects[] O) throws IOException {
    final int N_THREADS = Runtime.getRuntime().availableProcessors();
    BlockingQueue<Runnable> blockingQueue = new ArrayBlockingQueue<Runnable>(20);
    RejectedExecutionHandler rejectedExecutionHandler = new ThreadPoolExecutor.CallerRunsPolicy();
    ThreadPoolExecutor service =  new ThreadPoolExecutor(N_THREADS, N_THREADS, 0L, TimeUnit.MILLISECONDS, blockingQueue, rejectedExecutionHandler);
    final SomeObject RO = new SomeObject();
    for(String s : S){
        service.execute(new Runnable() {
            public void run() {
                // initialize variables
                for (Object o : O) {
                        V ps = RO.apply(sentence);
                        //more work on ps 
                }
                File f = new File("something");
                FileWriter fw = null;
                try {
                    fw = new FileWriter(f.getAbsoluteFile());
                    BufferedWriter bw = new BufferedWriter(fw);
                } catch (IOException e) {
                    System.out.println(f.getAbsoluteFile());
                }
                BufferedWriter bw = new BufferedWriter(fw);
                for (SentenceAnnotation entry : annotations) {
                    try {
                        bw.write(entry.toString());
                        bw.newLine();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }

                try {
                    bw.flush();
                    bw.close();
                    fw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });
    }
    service.shutdown();
    while (!service.isTerminated()) {
    }
    long timeEnd = System.currentTimeMillis();
}

其中 S 是一个大数组(数十万),O 的长度为 50。我的问题是关于 RO 对象。它是在外部创建的,并且如果您愿意的话,可以由所有线程“共享”。现在,当这段代码运行一段时间后,堆空间耗尽,这让我很困惑。我倾向于认为 RO 对象仍然使原本已完成的 Runnables 保持 Activity 状态并慢慢消耗内存。真的吗?我使用“free -m”监控了linux系统(最新版本的Oracle JDK)的内存消耗,我可以缓慢但肯定地看到内存消失。我非常感谢您给我的任何建议。

最佳答案

 try {
   fw = new FileWriter(f.getAbsoluteFile());
   BufferedWriter bw = new BufferedWriter(fw);
 } catch (IOException e) {
   System.out.println(f.getAbsoluteFile());
 }
 BufferedWriter bw = new BufferedWriter(fw);

您在这部分代码中泄漏了未关闭的BufferedWriter。您在 try 子句的作用域中创建第一个,但不要关闭它。引用消失,但运行时创建的任何 native 处理都不会被释放。您不会注意到,因为您随后立即为同一个文件创建了一个新的 BufferedWriter

关于java - Java中的多线程垃圾收集: Sharing object outside prevents GC?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19574229/

相关文章:

java - 我收到错误: java: '.class' expected, i think it has something to do with my for loop (I'm a begginner) [closed]

c++ - 如何在带参数的函数上使用 boost::call_once()

c - 在 2 个线程之间交替

java - 在java中删除一个对象,仅在数组列表中引用它

.net - .NET 中的 CUDA 全局内存释放问题

java - 如何在不使用 GPS、加速计的情况下检测设备是否静止

java - 将 @Pattern 与 Float 字段一起使用

java - java websocket 上线后如何发送离线用户的消息?

java - 如何使用线程运行类的方法

Android解除分配位图进入 "unknown"内存