【问题标题】:ProGuard optimization also remove #wait() callsProGuard 优化还删除了 #wait() 调用
【发布时间】: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


【解决方案1】:

您指定的-assumenosideeffects 选项似乎也与Object#wait() 匹配。 ProGuard 然后很高兴地为您删除这些调用。除了 ProGuard 手册中记录的选项之外,您可能不应该添加 -assumenosideeffects 选项。

【讨论】:

  • 是的,你是对的,我的意思是这是一个令人愉快的危险问题。我尝试删除我的每个“-assumenosideeffects”,直到找到杀手。它是“-assumenosideeffects class com.st.utils.ShapeCheck {*;}”。这意味着 Proguard 不仅会删除 ShapeCheck 中定义的方法,还会删除 'java.lang.Object' 中定义的所有方法!
猜你喜欢
  • 1970-01-01
  • 2013-04-25
  • 2011-08-25
  • 2012-10-24
  • 2014-06-01
  • 1970-01-01
相关资源
最近更新 更多