日志线程内存泄漏 [英] Log thread memory leak

查看:98
本文介绍了日志线程内存泄漏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经为程序编写了一个后台日志线程,如果一个类需要一个记录器,它将把它从我的线程池中拉出,因此对于每个文件名,只有一个日志正在运行.该类添加了需要通过log(String)记录的所有内容.

I have coded a background logging thread for my program, if a class needs a logger it pulls it from my threadpool, so for each filename there is only one log running. The class, adds anything which needs to be logged via log(String).

无论如何,只要我设置了登录名,并且过一会儿我就会得到heapoutofmemory异常,它将运行writetolog().这是由日志线程引起的,但是我看不到内存泄漏在哪里,而且我也不擅长线程.我唯一的想法是它在缓冲的编写器中?

Anyway whenever I set logging on and it runs the writetolog() after a while I get heapoutofmemory exception. This is caused by the log threads, but I can't see where the memory leak is, and I am not that great at threading. My only idea is that it is in the buffered writer?

import java.io.File;
import java.io.IOException;

import java.io.FileWriter;
import java.util.Calendar;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

public class Log extends Thread{
private String file;
private BlockingQueue<String> pq = new LinkedBlockingQueue<String>();
private BufferedWriter bw;
private boolean Writing;

@Depreciated
public Log(){
    super();
    file = "log.txt";

    start(); 
}

public Log(ThreadGroup tg, String fileName){
    super(tg,fileName);
    file = fileName;
    try {
        new File(file).createNewFile();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    start(); 
}

public Log(String fileName){
    file = fileName;
    try {
        new File(file).createNewFile();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    start(); 
}

@Override
public void run(){
    //System.out.println("Log Thread booted " +file);

    while(Run.running){
        if (!Writing){
            if(Run.logging)
            writeToLog();
        }
        try{
            Thread.sleep(500);
        }catch(InterruptedException e){
            Thread.currentThread().interrupt();
            break;
        }


    }
    //System.out.println("Log Thread shutting down " +file);
}

public synchronized void log(String s){
    if(Run.logging)
    pq.add(s);
}

private void writeToLog(){
    try{
        Writing = true;

        bw = new BufferedWriter(new FileWriter(file, true));
    while(!pq.isEmpty()){

            bw.write(Calendar.getInstance().getTime().toString() +" " +pq.poll());
            bw.newLine();

    }

    bw.flush();
    bw.close();
    Writing = false;
    }catch(Exception e){Writing = false; e.printStackTrace();}
}



}

编辑-值得一提的是,在程序的上下文中,它正在记录100到1000的行

EDIT - It is worth mentioning as well that in the context of the program it is logging 100's - 1000's of lines

非常感谢 山姆

推荐答案

如果您的后台线程无法足够快地写入磁盘,则

If your background thread doesn't write to the disk fast enough, the LinkedBlockingQueue (whose capacity you left unspecified) will grow until it contains Integer.MAX_VALUE strings. That's too much for your java heap size.

指定容量,以便在队列已满的情况下,调用log方法的线程将在队列中的日志的一部分转储到磁盘上时等待:

Specify a capacity so that, in case of a full queue, the thread calling the log method will wait while some part of the queued log is dumped on disk :

private BlockingQueue<String> pq = new LinkedBlockingQueue<String>(1000);

使用输入而不是log方法中的add,以便日志记录操作等待而不是引发异常.

Use put instead of add in the log method so that the logging operation waits instead of throwing an exception.

(您是否注意到您是在磁盘上写时间而不是在日志上写时间?)

(did you notice that you write the time at writing on disk instead of the time at logging ?)

这篇关于日志线程内存泄漏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆