【发布时间】: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