2012-05-08 2 views
2

Proguard가 내 응용 프로그램을 최적화하면 Object#wait()에 대한 모든 호출이 제거된다는 것을 알 수 있습니다.ProGuard 최적화는 또한 #wait() 호출을 제거합니다.

수동적으로 대기해야하는 각 스레드 (알림까지)가 현재 활발히 대기 중입니다 (100 % CPU 사용).

최적화가 -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

는 또한 Object#wait() 일치 -assumenosideeffects 옵션을 지정하는 것으로 나타났습니다. ProGuard는 행복하게 그 전화를 제거합니다. ProGuard 설명서에 설명 된 것 이외의 것을 -assumenosideeffects 옵션에 추가하면 안됩니다.

+1

예, 당신 말이 맞습니다. 결코 행복하지 않은 위험한 문제는 아닙니다. 살인자를 발견 할 때까지 내 '- 유산균 효능'을 제거하려고 노력했습니다. '- 클래스 분석 .Sutape.ShapeCheck {*;}'였습니다. 즉, Proguard는 ShapeCheck에 정의 된 메소드뿐만 아니라 'java.lang.Object'에 정의 된 모든 메소드를 제거합니다! – elou