java - Jooq/Java 常量池 64K 限制

标签 java class jooq

Quote from the Jooq manual :

Turning off the generation of the above files may be necessary for very large schemas, which exceed the amount of allowed constants in a class's constant pool (64k) or, whose static initialiser would exceed 64k of byte code

我确实理解这个问题,但是如何对此采取措施或计划。有没有人能很好地估计这是多少个表,每个表有多少列,具有合理的平均名称长度?我真的很欣赏这样一个事实,即这是一个“一段字符串有多长”类型的问题 - 但任何具有合理准确性或经验丰富的估计的公式都会受到赞赏。

最佳答案

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

GETSTATIC (reference)
PUTSTATIC (reference)

字节代码是单个字节,其中每个字段引用是一个两字节索引,使每个指令计数 6 个字节。由于静态初始值设定项需要以(隐式)return 语句结束,这会向该方法添加另一个字节。每个方法有 64kB - 1B 可用字节,每个字段有 6 个字节,这告诉我们初始化程序在超过限制之前每个类最多可以容纳 10.922 个这样的字段,即最多支持 (65536 - 1)/6 = 10.922 表、序列或键。

constant pool最多可以包含 65536 个条目。限制的计算有点困难,因为常量池不包含重复值,而是重用现有条目。我们针对没有名称被多次使用的最坏情况进行计算。

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

我们需要遵守这两个限制,因此 10.920 个表、序列或键 是您受约束的数字。

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

关于java - Jooq/Java 常量池 64K 限制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40673170/

相关文章:

java - bitmapFactory.decodefile 给出 null 作为输出

java - 改造 2 : @Query "encoded=false" don't work

class - 如何在Flutter中从另一个类访问一个类方法?

c++ - 创建链接列表的问题

java - JOOQ:通过主键获取单行?

java - 使用 "=="语句

java - 从 heightProperty() 和 widthProperty() 中获取最大值和最小值

java - 无法让一个类的方法使用 Java 中另一类的用户输入

java - 如何从JOOQ中的日期时间中仅提取日期部分

java - Jooq 不支持 Spring 事务