【问题标题】:Using a For loop with BigIntegers creates memory problems with Java. [Android]对 BigIntegers 使用 For 循环会在 Java 中产生内存问题。 [安卓]
【发布时间】:2015-10-26 19:22:13
【问题描述】:

我目前正在尝试像这样循环遍历 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%,有人知道这是为什么吗?

感谢阅读:)

【问题讨论】:

  • 你认为你的 for 循环在做什么?
  • @Kayaman 你是什么意思?
  • 那么,你为什么不使用for(int i = 0;i &lt; 17;i++),而完全没有理由地使用BigInteger
  • y.compareTo(yu.add(y)) &lt; 0 说“y 小于 y + 17”,这始终是正确的,因此您创建了一个无限循环。你想做什么?
  • 要明确:9223372036854775807long 的限制。对于int 循环变量,最大值为2147483647

标签: java android for-loop memory biginteger


【解决方案1】:
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 中的“分配跟踪器”工具。它会显示您所有的分配,以及每个分配的位置。它应该可以帮助您追踪所有这些垃圾对象的来源。

但是,是的,就像问题上的 cmets 已经说明的那样:您的循环将永远进行,并创建大量 BigInteger 对象——因为每个 add() 调用都会分配一个新的 BigInteger。由于它永远存在,这些数字会变得非常大,也会增加每个 BigInteger 对象的大小。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-09
    • 1970-01-01
    • 1970-01-01
    • 2016-01-20
    • 1970-01-01
    相关资源
    最近更新 更多