使用局部变量与场对GC的影响

时间:2013-02-02 20:50:32

标签: java android dalvik

我在onDraw()方法的调用堆栈中有一个3级的方法。它被称为数百次,有时每次重绘数千次。我已经对onDraw()方法进行了大量的分析,我可以看到以下方法占总数的14%,所以绝对值得一看。我需要在压缩缩放和拖动操作期间提高帧速率。

private void getVisiblePointsFromPath(){

   double longRads = longitude * (Math.PI / 180);
   double latRads = latitude * (Math.PI / 180);

   ...

}

当方法退出并且双打超出范围时,我认为他们有资格获得GC,尽管我知道这可能发生的时间是非确定性的。

这样做有什么好处:

public class GisView extends ImageView{

    private double longRads;
    private double latRads;

    private void getVisiblePointsFromPath(){

       longRads = longitude * (Math.PI / 180);
       latRads = latitude * (Math.PI / 180);

       ...

    }

}

我认为这个习惯用法会导致双打被取消,然后在每次传球时被重新分配,但不会产生额外的垃圾,从而减少了我造成的GC数量。或者虚拟机比那更聪明吗?

请注意,我的问题本身不是“哪个更快”,而是关于哪个可能导致GC减少。我可以测量速度差异,但我不太了解Dalvik VM和Android GC来预测哪个导致更少的垃圾。

1 个答案:

答案 0 :(得分:7)

  

我认为这个习惯用法会导致双打被取消,然后在每次传球时被重新分配,但不会产生额外的垃圾,从而减少了我造成的GC数量。或者虚拟机比那更聪明吗?

Primitive local variables live on the stack,而不是堆,所以他们根本不需要GC。一旦函数返回,它们就会立即消失 - 因为它会清除堆栈帧。

那就是说,是的,每次传球都会重新分配双打 ,因为这就是你写的代码所说的。如果您想提高此特定方法的速度,请在设置longRadslatRads计算longitudelatitude 。正确的方法是始终委托将这些字段设置为setter方法。例如:

public void setLongitude(double longitude) {
    this.longitude = longitude;
    this.longRags = longitude * (Math.PI / 180);
}

当然,这会使设置速度变慢,但这并不是您对优化的要求。