【问题标题】:BigInteger cosumes a lot of memoryBigInteger 占用大量内存
【发布时间】:2016-04-13 08:38:01
【问题描述】:

我有以下代码要测试:

import java.math.BigInteger;
import java.util.Random;

public class TestBigInteger {

    public static void main(String[] args) {
        BigInteger bigInteger = BigInteger.probablePrime(32, new Random())
                .multiply(BigInteger.probablePrime(32, new Random()));
        BigInteger n = BigInteger.probablePrime(20, new Random());
        while (!Thread.interrupted()) {
            bigInteger.mod(n);
        }

    }
}

我从 jconsole 得到了以下情节:

为什么会这样?如果我的 bigInteger 只有 64 位长度,为什么 mod 操作会占用大量内存?

【问题讨论】:

  • 因为垃圾收集器不会在每个对象之后运行,它会在内存达到一定阈值时运行,然后清理所有旧引用
  • 嗯,它正在制造垃圾。 BigInteger.mod() 创建了几个你刚刚扔掉的对象。但是,您可以看到 GC 每隔一段时间就会收到垃圾。
  • 为什么说 BigInteger 是 8 字节?作为对象,它至少有 12 字节的头部和信息。我不知道 BigInteger 的内部结构,但我认为它远远超过 8 个字节的信息。此外,对象排列为 8 的倍数.. 所以.. 真的不能是 64 位
  • @Jack,我的意思是 bigInteger 是产生两个 32 位数字。所以我认为 bigInteger 是 64 位的。

标签: java memory garbage-collection biginteger jconsole


【解决方案1】:

这并没有保留很多内存,而是产生了很多垃圾。

    while (!Thread.interrupted()) {
        bigInteger.mod(n); // create a new objects each time.
    }

这个循环尽可能快地创建垃圾(也需要一点 CPU 工作)因此您应该会看到内存使用非常活跃。

如果我的 bigInteger 只有 64 位长度,为什么 mod 操作会占用大量内存?

这使得内存使用率更高,因为执行计算的实际 CPU 花费量相对较小。如果你有一个更大的数字,与创建对象相比,它会花费更多的时间来使用 CPU。与它使用的 CPU 相比,它花费了更多时间来创建垃圾。

顺便说一句,我建议您使用 Java 6 的 VisualVM 和 Java 7 的 Java Mission Control,而不是 jconsole。

【讨论】:

    【解决方案2】:

    函数BigInteger.mod 正在使用BigInteger.remainder 函数,它创建了几个MutableBigInteger 对象。

    你正在通过调用创建很多对象:

     while (!Thread.interrupted()) {
            bigInteger.mod(n); // create a new large object each time.
     }
    

    【讨论】:

    • 我注意到数字是“64 位”后更改了我的评论。 ;)
    • 好的,我注意到了:)
    猜你喜欢
    • 2014-05-11
    • 2011-02-27
    • 2013-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多