繁体   English   中英

为什么这会超过Java构造函数和静态初始化程序中的65,535字节限制?

[英]Why does this exceed the 65,535 byte limit in Java constructors and static Initializers?

免责声明:我意识到我可以在运行时用Java生成这个,这是一个非常特殊的情况下需要的,同时性能测试一些代码。 我发现了一种不同的方法,所以现在这只是一种好奇心而不是任何实际的东西。

我已经尝试了以下作为静态字段,作为实例字段,并直接在构造函数中初始化。 每次eclipse通知我“构造函数TestData()的代码超过65535字节限制”或“静态初始化程序的代码超过65535字节限制”。

有10,000个整数。 如果每个int是4个字节(32位),那么那不是40,000个字节吗? 除了仅构建数组的数据之外,还有更多的25,0000字节的开销吗?

使用这一小段python生成数据:

#!/usr/bin/python

import random;
print "public final int[] RANDOM_INTEGERS = new int[] {";
for i in range(1,10000):
    print str(int(random.uniform(0,0x7fffffff))) + ",";
print "};";

这是一个小样本:

public final int[] RANDOM_INTEGERS = new int[] {
    963056418, 460816633, 1426956928, 1836901854, 334443802, 721185237, 488810483,
    1734703787, 1858674527, 112552804, 1467830977, 1533524842, 1140643114, 1452361499,
    716999590, 652029167, 1448309605, 1111915190, 1032718128, 1194366355, 112834025,
    419247979, 944166634, 205228045, 1920916263, 1102820742, 1504720637, 757008315,
    67604636, 1686232265, 597601176, 1090143513, 205960256, 1611222388, 1997832237,
    1429883982, 1693885243, 1987916675, 159802771, 1092244159, 1224816153, 1675311441,
    1873372604, 1787757434, 1347615328, 1868311855, 1401477617, 508641277, 1352501377,
    1442984254, 1468392589, 1059757519, 1898445041, 1368044543, 513517087, 99625132,
    1291863875, 654253390, 169170318, 2117466849, 1711924068, 564675178, 208741732,
    1095240821, 1993892374, 87422510, 1651783681, 1536657700, 1039420228, 674134447,
    1083424612, 2137469237, 1294104182, 964677542, 1506442822, 1521039575, 64073383,
    929517073, 206993014, 466196357, 1139633501, 1692533218, 1934476545, 2066226407,
    550646675, 624977767, 1494512072, 1230119126, 1956454185, 1321128794, 2099617717,
    //.... to 10,0000 instances

以下是使用{1000001,1000002,1000003}初始化数组的字节码:

 5  iconst_3
 6  newarray int [10]
 8  dup
 9  iconst_0
10  ldc <Integer 1000001> [12]
12  iastore
13  dup
14  iconst_1
15  ldc <Integer 1000002> [13]
17  iastore
18  dup
19  iconst_2
20  ldc <Integer 1000003> [14]
22  iastore
23  putfield net.jstuber.test.TestArrayInitializingConstructor.data : int[] [15]

因此,对于这个小数组,每个元素需要5个字节的Java字节码。 对于较大的数组,数组索引和常量池的索引将对大多数元素使用3个字节,这导致每个数组元素8个字节。 因此,对于10000个元素,您必须预期大约80kB的字节代码。

使用16位索引初始化大数组的代码如下所示:

2016  dup
2017  sipush 298
2020  ldc_w <Integer 100298> [310]
2023  iastore
2024  dup
2025  sipush 299
2028  ldc_w <Integer 100299> [311]

数组文字被转换为使用值填充数组的字节代码,因此每个数字需要更多的字节。

为什么不将数据移出到在静态初始化程序块中的类加载时加载的资源中? 这可以通过使用MyClass.class.getClassLoader().getResourceAsStream()轻松完成。 无论如何,它似乎就在它所属的地方。

或者更好的是,使用可用的Java工具在静态初始化程序块中创建随机值。 如果你需要可重复的“随机”数字,那么每次只用固定但随机选择的数字为Random实例播种。

除了整数的值之外,构造函数和初始化程序还需要包含用于将整数加载到数组中的JVM指令。

一种更简单,更实用的方法是将数字存储在文件中,可以是二进制格式,也可以是文本格式。

我不知道java以这种方式初始化数组,但它没有有效地初始化大数组。

我认为字符的代码大小超过65535.不是10000整数占用的内存。

我认为这可能是以字母数字表示这些整数所需的内存量。 我认为这个限制可能适用于代码本身,因此,每个int,例如:1494512072实际上需要10个字节(每个数字一个)而不是仅用于int32的4个字节。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM