我正在读这本书,题为“破解Laakman的编码访谈”。她(作者p.g.202)做过这一部分:
byte[] bitfield = new byte [0xFFFFFFF/8];//there are 7 F's
她分配了40亿比特。但是,不是0xFFFFFFF = 2 ^ 28-1?因此,她只分配了一个2 ^ 28-1 / 8字节的字节数组,这个数组远不接近40亿比特。它只有2 ^ 28-1位。我的问题是 - 她错了还是我做错了什么?我们如何分配40亿比特?我试过了:
byte[] bitfield = new byte[0xfffffff *2];
虽然上面导致jvm用尽了堆空间。
虽然我们在这里,但最好的是表达十六进制值?例如0xffffffff还是0xFFFFFFFF?
答案 0 :(得分:5)
我不清楚你为什么乘以2.最简单的方法就是采用(40亿/ 8)的十六进制表示 - 其中“40亿”我们的意思是0x100000000。
因此使用0x100000000 / 8,即0x2000000:
byte[] array = new byte[0x20000000];
如果你已经在启动时为你的JVM提供了足够的内存,那应该没问题。与-Xmx900M。
示例代码:
public class Test {
public static void main(String[] args) {
byte[] bytes = new byte[0x20000000];
}
}
默认运行:
c:\Users\Jon\Test>java Test
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at Test.main(Test.java:3)
运行更多空间:
c:\Users\Jon\Test>java -Xmx900M Test
答案 1 :(得分:1)
作为迂腐者,我会说40亿不完全是2 ^ 32我建议使用BitSet,它不能容纳这么多位但是2 BitSet可以
BitSet[] bitSets = { new BitSet(2 * 1000 * 1000 * 1000),
new BitSet(2 * 1000 * 1000 * 1000) };
如果它必须是2 ^ 32位或4 Gb(小写b
是位),对于两个bitSets来说这略微有点。
BitSet[] bitSets = { new BitSet(1 << 28),
new BitSet(1 << 28),
new BitSet(1 << 28),
new BitSet(1 << 28) };
// set a bit
long bitToSet =
bitSets[(int) (bitToSet >>> 28)]
.set((int) (bitToSet % (1 << 28)), value);
// test is set
long bitToTest =
boolean test = bitSets[(int) (bitToTest >>> 28)]
.get((int) (bitToTest % (1 << 28)));
显然,您使用的任何方法都希望将数组包装在一个隐藏其实现细节的集合中。
答案 2 :(得分:1)
整数的MAX_VALUE为0X7fffffff。我相信她在宣布时错过了数字'7'。由于策略是使用位位置来指示整数值(即每个字节有8位可以容纳多达8个整数),所以她分配了数组来保存40亿个整数。
byte x[] = new byte[0x7fffffff/8];
答案 3 :(得分:0)
我通过这些数字的第一次小跑得出了2,147,483,640位 - 大约20亿。
[哎呀 - 错过了8分。现在我得到了268,435,448位。]
[您可以在Java中分配的最大大小的对象将取决于您声明的/默认的堆大小限制和JVM设计的详细信息。例如,有些将无法分配大于16MB的单个对象,而其他对象可能限制为64MB等。]
答案 4 :(得分:0)
要获得40亿比特,您需要500,000,000(5亿)字节。这是488281.25K或~487 meg。为了在内存中分配它,您很可能需要向上调整JVM的堆大小。
这本书似乎有8个F或者有一个类型。
答案 5 :(得分:0)
根据发布的信息,我会说你是对的。然而(考虑到亿元作为短期亿元,109),我能想到的“分配40亿比特”的方式是:
byte[] bitfield = new byte [1000 * 1000 * 1000 / 8 * 4];
分配的数组长度为500MB(根据您的默认值可能需要额外的-Xmx):
bitfield.length
500000000 (base 10)
0x1DCD6500 (base 16)
顺便说一句:我通常用大写字母表达基数16
另一方面,亿元有些含糊不清(见规模与长期规模): Wikipedia Billion Java Primitive Data Types
答案 6 :(得分:0)
这可能是一个错误,因为她想要代表40亿个整数。 分配到0xFFFFFFFF / 8将保持全部40亿,因为每个字节保持8位。 4年前我把它添加到她的勘误表中,但是她把我吹走了。 :|
答案 7 :(得分:0)
我非常确定她错过了F-它应该是0xFFFFFFFF(8Fs)= 2 ^ 32〜40亿字节= 320亿位=> 0xFFFFFFFF / 8 = 40亿位。每个位代表一个从1到40亿的数字。