BigInteger占用了大量内存

3

我有以下代码需要测试:

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中得到了以下的图表:

enter image description here

为什么会这样呢?如果我的bigInteger只有64位长度,为什么模运算会占用很多内存?


因为垃圾回收器不会在每个对象之后运行,它会在内存达到一定阈值时运行,然后清理所有旧引用。 - Ferrybig
嗯,它正在创建垃圾。BigInteger.mod()会创建多个对象,而你只是将它们丢弃。但是你可以偶尔看到GC清理这些垃圾。 - Kayaman
1
为什么你说BigInteger是8字节?作为对象,它至少有12个字节的头部加上信息。我不知道BigInteger的内部结构,但我认为它的信息远远超过8字节。此外,对象按8的倍数排列..所以..真的不能是64位。 - Jack
@Jack,我的意思是bigInteger是两个32位数字的乘积。所以我认为bigInteger是64位的。 - Tony
2个回答

7
这并不是保留了大量内存,而是产生了很多垃圾。
    while (!Thread.interrupted()) {
        bigInteger.mod(n); // create a new objects each time.
    }

这个循环尽可能快地创建垃圾(还有一点CPU工作),因此您应该预期看到内存使用情况非常活跃。
为什么模数运算会占用大量内存,即使我的bigInteger只有64位长度?
这会增加内存使用量,因为计算所花费的实际CPU时间相对较少。如果您有一个更大的数字,它将比创建对象使用更多的CPU时间。现在它花费更多的时间来创建垃圾,而不是使用CPU。
顺便说一句,我建议使用Java 6的VisualVM和Java 7的Java Mission Control,而不是jconsole。

3

函数BigInteger.mod使用了BigInteger.remainder函数,该函数会创建一些MutableBigInteger对象。

而您通过调用以下代码创建了大量对象:

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

我在注意到数字是“64位”之后改变了我的评论。 ;) - Peter Lawrey
好的,我注意到了 :) - user987339

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接