2012-05-08 1 views
2

Когда Proguard оптимизирует мое приложение, он швыряет, что все вызовы Object#wait() удаляются.Оптимизация ProGuard также удаляет вызовы #wait()

Так что каждый поток, который должен пассивно ждать (пока уведомление), теперь активно ждет (100% использования ЦП).

Когда оптимизация завершается с -dontoptimize, все в порядке.

Мне нужна оптимизация для удаления какого-либо метода с помощью -assumenosideeffects, я ищу, что не так.
Можно ли сохранить все вызовы до Object#wait() для оптимизации (удаления)?

Есть ли другое решение?

EDIT 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; 
    } 
+2

У вас есть короткая, но полная программа, которая демонстрирует проблему? Вы действительно подтвердили, что вызовы 'wait()' действительно удаляются? Возможно ли, что у вас на самом деле есть какой-то ошибочный код, а оптимизация просто делает этот недостаток более заметным? –

+0

Я добавил пример, демонстрирующий эту проблему – elou

+1

monitorenter уже присутствовал бы из-за синхронизированного блока ... так что вызов 'wait' не заменяется * на это. Если он * удален *, то да, это звучит как ошибка. Опять же, короткий, но * полный * пример (в идеале полный класс, который можно скомпилировать, а затем командную строку, которую вы используете для Proguard) облегчит жизнь тем, кто пытается воспроизвести проблему. –

ответ

6

Вы, кажется, указав -assumenosideeffects опции, которые также соответствуют Object#wait(). ProGuard затем счастливо удаляет эти вызовы для вас. Вероятно, вам не следует добавлять опции -assumenosideeffects, кроме тех, которые описаны в руководстве ProGuard.

+1

Да, вы правы, и тем более я имею в виду, что это очень опасная проблема. Я пытаюсь удалить каждый из моих «-assumenosideeffects», пока не найду убийцу. Он был «-assumenosideeffects class com.st.utils.ShapeCheck {*;}». Это означает, что Proguard не только удаляет метод, определенный в ShapeCheck, но также и весь метод, определенный в 'java.lang.Object'! – elou

 Смежные вопросы

  • Нет связанных вопросов^_^