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

StackOverflow https://stackoverflow.com/questions/788787

  •  16-09-2019
  •  | 
  •  

免责声明:我知道我可以在Java运行时产生这个,这是需要一个非常特殊的情况下,同时性能测试一些代码。我发现了不同的方法,所以现在这只是更多的比什么实际的好奇。

我尝试以下作为静态字段,作为实例字段,并且在构造函数中直接初始化。每次日食通知我任一“构造TESTDATA()的代码被超过65535个字节极限”或“用于...的静态初始化的代码被超过65535个字节极限”。

有万个整数。如果每个int是4个字节(32位),然后将其不40000个字节?是否真的有更多的,除了数据只知道一味构建阵列25,0000字节的开销?

在数据与蟒的这个小位产生的:

#!/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实例与固定的,但每次随机choosen数量。

除了整数的值,构造和初始化需要包含用于加载整数为阵列的JVM指令。

一个更简单,更实用的方法是页码存储在一个文件中,无论是在二进制格式或文本。

我不知道是什么的Java数组初始化这种方式,但它并没有有效地初始化大数组。

我认为在字符代码大小超过65535不受10000个整数采取的存储器。

我认为这是可能的,这是记忆到字母数字表示的那些整数所需的量。我认为这种限制可能申请代码本身,所以,每个INT,例如:1494512072其实需要用于INT32 10个字节(每一个位),而不是只有4字节

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top