【发布时间】:2015-10-09 23:36:49
【问题描述】:
当 Proguard 优化我的应用程序时,所有对 Object#wait() 的调用都会被删除。
因此每个应该被动等待(直到通知)的线程现在都在主动等待(100% CPU 使用率)。
当使用-dontoptimize 关闭优化时,一切正常。
我是否需要优化以删除 -assumenosideeffects 的某些方法,我正在寻找问题所在。
是否可以保留对 Object#wait() 的所有调用以进行优化(删除)?
还有其他解决办法吗?
编辑 1: 例如这段代码:
@Override
public void run() {
isRunning = true;
try {
while (isRunning) {
if (parent.isActivate) {
parent.updateDriveButtons();
synchronized (this) {
wait(1000);
}
}
else {
synchronized (this) {
// Wait for that the page is activated.
Utils.wait(this);
}
}
}
}
catch (Throwable e) {
e.printStackTrace();
}
finally {
isRunning = false;
}
}
正在被此代码替换(在反编译优化代码后):
wait() 已被删除,只有同步可见 monitorenter; ... monitorexit;
public final void run()
{
this.isRunning = true;
try {
while (this.isRunning) {
if (this.parent.isShowing()) {
...
monitorenter;
monitorexit; continue;
}
monitorenter;
monitorexit;
}return;
} catch (Throwable localThrowable) {
Object Ljava/lang/Object;;
return;
} finally {
this.isRunning = false; } throw localObject1;
}
【问题讨论】:
-
你有一个简短但完整的程序来演示这个问题吗?您是否真的验证了对
wait()的调用确实被删除了?有没有可能你实际上只是有一些有缺陷的代码,而优化只是让这个缺陷更加明显? -
我添加了一个例子来演示这个问题
-
monitorenter 由于同步块已经存在...所以
wait调用不会被那个替换。如果它被 removed 那么是的,这听起来像一个错误。同样,一个简短但完整的示例(理想情况下是一个可以编译的完整类,然后是您用于 Proguard 的命令行)将使那些试图重现该问题的人的生活更轻松。 -
感谢您的评论,这让我有精力尝试隔离问题。制作一个尝试重现此问题的小应用程序是不可能的,但它有助于找到解决方案。
标签: java multithreading optimization proguard