【发布时间】:2016-12-06 18:31:50
【问题描述】:
关闭生成上述文件可能是非常必要的 大型模式,超过类中允许的常量数量 常量池(64k)或,其静态初始化器将超过 64k 字节码
我确实了解这个问题,但是如何对此进行衡量或计划。有人对合理平均名称长度的每个表有多少个表有多少列有一个很好的估计吗?我真的很欣赏这是一个“一条字符串有多长”类型的问题 - 但任何具有合理准确性或经验丰富的估计的公式都值得赞赏。
【问题讨论】:
关闭生成上述文件可能是非常必要的 大型模式,超过类中允许的常量数量 常量池(64k)或,其静态初始化器将超过 64k 字节码
我确实了解这个问题,但是如何对此进行衡量或计划。有人对合理平均名称长度的每个表有多少个表有多少列有一个很好的估计吗?我真的很欣赏这是一个“一条字符串有多长”类型的问题 - 但任何具有合理准确性或经验丰富的估计的公式都值得赞赏。
【问题讨论】:
JOOQ 代码生成器在代码库中为每个表/序列/键添加一个字段。代码生成器已经保证代码只设置这个字段而不创建任何复杂的语句,从而减少了代码大小。由于该字段是静态的,这进一步减少了所需的字节码。每个初始化指令是一对字段读取和字段写入。在字节码中,每条这样的指令是:
GETSTATIC (reference)
PUTSTATIC (reference)
字节码是单个字节,其中每个字段引用是一个两字节索引,使每条指令计数为 6 个字节。由于静态初始化程序需要以(隐式)return 语句结束,这会向方法添加另一个字节。每个方法 64kB - 1B 可用字节和每个字段 6 个字节,这告诉我们初始化程序在超过限制之前每个类最多可以保存 10.922 个此类字段,即最多支持 (65536 - 1) / 6 = 10.922 表、序列或键。
constant pool 最多可以包含 65536 个条目。限制的计算有点困难,因为常量池不包含重复值,而是重用现有条目。我们会针对最坏的情况进行计算,即没有多次使用名称。
每个字段引用都是类引用和名称和类型引用的组合。类引用包含对具有类型名称的字符串的另一个引用。名称和类型引用包含对字段名称和字段描述符的两个引用作为字符串。 set 指令的所有者类型总是重复的,我们假设 get 指令在最坏的情况下从不重复,每个指令对占 2 个条目。对于每个指令对,set 和 get 字段的类型和名称总是相等的,这说明每个指令对有两个条目。包装名称和类型条目对于双方始终是唯一的,每个指令对占两个条目。这给我们留下了每个指令对的2 + 1 + 1 + 2 = 6 条目。 set 指令的所有者类型将始终在常量池中,因为它需要定义类。此外,我们需要考虑定义类的名称和默认构造函数等基本信息。幸运的是,注释具有源保留,因此它们被排除在类文件之外。一般的内务管理需要 12 个条目,这给我们留下了 (65536 - 12) / 6 = 10.920 表、序列或键。
我们需要遵守这两个限制,因此 10.920 个表、序列或键是您所受约束的数字。
请注意,由于为内部类属性定义了常量池条目,实际数量可能会更低。这会为每个内部类生成额外的内部类引用,从而减少空闲条目的数量。如果你保持在 10.000 个元素以下,我想你不会遇到任何麻烦。
【讨论】: