2016-11-18 40 views
4

Quote from the Jooq manualJooq/Java的常量池64K限制

关闭上述文件的产生可能需要很 大型模式,其中超过一类的 常量池允许常量的量(64K ),或者,其静态初始化器将超过64K 字节码

我明白的问题,而是如何做这一个措施或计划。有人估计有多少表格,每个表格有多少个合理的平均名称长度?我真的很欣赏这样的事实,即“一段串”的问题类型 - 但任何合理准确的公式或经验丰富的估计都值得赞赏。

回答

7

JOOQ代码生成器在代码库中为每个表/序列/键添加一个字段。代码生成器已经确保代码只设置此字段,但不会创建任何复杂的语句,从而减少代码大小。由于该字段是静态的,这进一步减少了所需的字节码。每个初始化指令都是一对字段读取和一个字段写入。在字节代码,每一个这样的指令为:

GETSTATIC (reference) 
PUTSTATIC (reference) 

字节码是其中,每个字段参考是一个两个字节的索引使每个指令计数的6个字节一个字节。由于静态初始化器需要以(隐式)返回语句结束,因此会向该方法添加另一个字节。每个方法有64kB - 1B可用字节和每个字段有6个字节,这告诉我们初始化器在超过限制之前最多可以保持每类10.922个这样的字段,即支持最多(65536 - 1)/6 = 10.922表,序列或密钥。

constant pool最多可包含65536个条目。由于常量池不包含重复值,但重新使用现有的条目,因此计算限制会更困难。我们计算最糟糕的情况,那就是没有使用多于一次的名字。

每个字段引用是一个类引用和名称和类型引用的组合。类引用包含对具有该类型名称的字符串的另一个引用。名称和类型引用包含对字段名称和字段描述符的两个引用作为字符串。设置指令的所有者类型总是重复的,我们假设get指令在最坏的情况下从不重复,每条指令对计算2个条目。每个指令对的set和get字段的类型和名称总是相等的,每个指令对的两个条目相关。包装名称和类型条目对于双方都是唯一的,每个指令对记录两个条目。这使我们每条指令对有2 + 1 + 1 + 2 = 6个条目。设置指令的所有者类型将始终位于常量池中,因为它需要定义类。此外,我们需要考虑基本信息,如定义的类的名称及其默认构造函数。幸运的是,注释具有源保留,因此它们被排除在类文件之外。一般管家需要12个条目,我们用(65536 - 12)/6 = 10.920表格,序列或密钥。

我们需要尊重两个限制,因此10.920表,序列或密钥是您绑定的数字。

请注意,由于为内部类属性定义了常量池条目,实际数量可能会更低。这会为每个内部类生成额外的内部类引用,从而减少可用条目的数量。如果你保持低于10,000个元素,我想你不会遇到任何麻烦。