在BigIntegers中使用For循环会导致Java出现内存问题。 [Android]产品

时间:2015-10-26 19:22:13

标签: java android for-loop memory biginteger

我目前正试图像这样循环一个BigInteger ......

BigInteger y;
BigInteger yu = BigInteger.valueOf(17);
for(y= new BigInteger("96");y.compareTo(yu.add(y)) < 0;y=y.add(BigInteger.ONE)){
      Toast.makeText(getApplicationContext(),"y="+y,Toast.LENGTH_SHORT).show();



        }

出于本例的目的,我只使用了96,但更高的数字也会出现同样的情况。当我开始该程序时,屏幕变黑并且log.cat显示以下消息:

10-26 19:15:49.853 5043-5043/everything.ofjd.com.everythingform D/dalvikvm: GC_FOR_ALLOC freed 9202K, 48% free 16294K/30792K, paused 162ms, total 162ms

10-26 19:15:50.923 5043-5043/everything.ofjd.com.everythingform D/dalvikvm: GC_FOR_ALLOC freed 9530K, 52% free 14955K/30792K, paused 155ms, total 156ms

10-26 19:15:51.983 5043-5043/everything.ofjd.com.everythingform D/dalvikvm: GC_FOR_ALLOC freed 9037K, 55% free 14110K/30792K, paused 146ms, total 147ms

10-26 19:15:53.018 5043-5043/everything.ofjd.com.everythingform D/dalvikvm: GC_FOR_ALLOC freed 8207K, 55% free 14094K/30792K, paused 141ms, total 141ms

10-26 19:15:54.068 5043-5043/everything.ofjd.com.everythingform D/dalvikvm: GC_FOR_ALLOC freed 8172K, 55% free 14114K/30792K, paused 143ms, total 143ms

只要应用程序正在运行,Log.cat会继续记录55%,有人知道这是为什么吗?

感谢阅读:)

1 个答案:

答案 0 :(得分:2)

10-26 19:15:49.853 5043-5043/everything.ofjd.com.everythingform D/dalvikvm: GC_FOR_ALLOC freed 9202K, 48% free 16294K/30792K, paused 162ms, total 162ms
10-26 19:15:50.923 5043-5043/everything.ofjd.com.everythingform D/dalvikvm: GC_FOR_ALLOC freed 9530K, 52% free 14955K/30792K, paused 155ms, total 156ms
10-26 19:15:51.983 5043-5043/everything.ofjd.com.everythingform D/dalvikvm: GC_FOR_ALLOC freed 9037K, 55% free 14110K/30792K, paused 146ms, total 147ms
10-26 19:15:53.018 5043-5043/everything.ofjd.com.everythingform D/dalvikvm: GC_FOR_ALLOC freed 8207K, 55% free 14094K/30792K, paused 141ms, total 141ms
10-26 19:15:54.068 5043-5043/everything.ofjd.com.everythingform D/dalvikvm: GC_FOR_ALLOC freed 8172K, 55% free 14114K/30792K, paused 143ms, total 143ms

让我们一点一点地说:

  • GC_FOR_ALLOC表示我们必须进行垃圾收集,因为您没有空间进行分配。
  • freed 9202K表示GC设法释放大约9 MB的RAM,所以这很好。
  • 48% free 16294K/30792K表示现在,大约有一半的堆正在使用中。有大约14 MB的可用堆空间。
  • paused 162ms表示您的线程必须等待0.162秒才能运行此垃圾收集。

现在,你为什么要看到所有这些?

因为您正在分配和丢弃大量对象。那些垃圾收集器一直在释放的~9 MB?它们来自不再引用的对象。

我建议您使用Android DDMS中的“分配跟踪器”工具。它会显示您的所有分配,以及每个分配的位置。它应该可以帮助您跟踪正在创建的所有这些垃圾对象的来源。

但是,是的,就像问题上的评论已经说过:你的循环是永远的,并创建了大量的BigInteger对象 - 因为每个add()调用都将分配一个新的BigInteger。由于它永远存在,这些数字将变得非常大,同时也会增加每个BigInteger对象的大小。

但严重的是,尝试“分配跟踪器”工具。很高兴知道,你会更好地了解这里出了什么问题。