【问题标题】:long gc collection in java when changing boolean variable from a thread从线程更改布尔变量时java中的长gc集合
【发布时间】:2013-12-29 21:53:19
【问题描述】:

我遇到了奇怪的问题,我花了很长时间才找出原因, 我有一个启动一个简单线程的类:

public class ServerConnector implements Handler {

private ConcurrentLinkedQueue<ImagePackage> queue;
private  boolean isDuringSend;
private String requestId;
private boolean isRunning;
private boolean done;
private ImagePackage packet;
private Context context;

public ServerConnector(Context context) {
    packet = null;
    this.context = context;
    done = false;
    requestId = null;
    isDuringSend = false;
    queue = new ConcurrentLinkedQueue<ImagePackage>();
}

public void add(ImagePackage packet) {
    if (packet.getImage() != null) {
        synchronized (queue) {
            queue.add(packet);
            queue.notifyAll();
        }

    }

}

public void start() {
    isRunning = true;

    Thread t = new Thread(new Runnable() {
        ImagePackage packet = null;

        @Override
        public void run() {

            while (isRunning) {
                if (!isDuringSend) {

                    packet = getElementFromQueue();
                    if (packet == null) {

                        continue;
                    }

                    try {


                        isDuringSend = true;
                    //  processQueue(packet);
                    } catch (Exception e) {

                        Intent intent = new Intent(context,
                                LoadingActivity.class);
                        context.startActivity(intent);
                        isDuringSend = false;

                    }
                }
            }
        }
    });
    t.start();

}

现在 GC 工作了,他需要 300 毫秒才能清除所有内容:

  12-29 23:41:06.937: D/dalvikvm(14102): GC_FOR_ALLOC freed 0K, 16% free 13788K/16244K, paused                    271ms, total 271ms
  12-29 23:41:07.257: D/dalvikvm(14102): JIT unchain all for threadid=16
  12-29 23:41:07.287: D/dalvikvm(14102): GC_FOR_ALLOC freed 69K, 6% free 15289K/16244K, paused 270ms, total 272ms
  12-29 23:41:07.567: D/dalvikvm(14102): JIT unchain all for threadid=16 
  12-29 23:41:07.848: D/dalvikvm(14102): JIT unchain all for threadid=16
  12  -29 23:41:07.868: D/dalvikvm(14102): GC_EXPLICIT freed 3036K, 21% free 13858K/17460K,   paused   254ms+256ms, total 545ms

但是当我从代码中删除这个简单的行“is during send = false”时,基本上只是从线程内部将布尔字段切换为 true,GC 清理时间将减少到 ~ 40 毫秒。

有什么想法,请问为什么会这样?

public void start() {
    isRunning = true;

    Thread t = new Thread(new Runnable() {
        ImagePackage packet = null;

        @Override
        public void run() {

            while (isRunning) {
                if (!isDuringSend) {

                    packet = getElementFromQueue();
                    if (packet == null) {

                        continue;
                    }

                    try {


                        isDuringSend = true;
                    //  processQueue(packet);
                    } catch (Exception e) {

【问题讨论】:

  • 看起来您的线程非常占用 CPU,因此 GC 需要更多时间
  • 为什么会占用大量 CPU?更重要的是,如果我从线程内部分配新对象,GC 会很快清理它,即使它“消耗”更多内存,它只是导致它的 serverconnector 类中的一个字段的布尔值

标签: java android multithreading garbage-collection


【解决方案1】:

我有一个类似的问题,即 GC 导致我的应用程序滞后,已解决将“volatile”添加到可以从另一个线程更改的变量中,在您的情况下,它将是“isDuringSend”变量。

在我的情况下,我不知道是什么原因造成的,所以你的问题确实帮助我找到了问题。

【讨论】:

  • 我很高兴听到我的帖子对您​​有所帮助:),这确实是一个我还没有弄清楚的奇怪问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-11-30
  • 2022-09-25
  • 2011-08-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多