Ограничения байт-кода JVM для взаимодействия классов классов
Я просматривал инструкции JVM bytecode и был удивлен, увидев, что все взаимодействия между классами (например, casting, new
и т.д.).) полагаются на постоянный поиск в пул для идентичности других классов.
Правильно ли вы заключаете, что это означает, что один класс не может знать о существовании более чем 64 тыс. других, поскольку их невозможно ссылаться? Если нужно было сослаться на это много, что нужно делать - делегировать работу нескольким классам, каждый из которых может иметь свои собственные < 64k взаимодействия?
(Причина, по которой это меня интересует, заключается в том, что у меня есть привычка писать генераторы кода, иногда производя тысячи различных классов, и что некоторые языки (например, Scala) создают классы в избытке. Поэтому кажется, что если true, будьте осторожны: если у меня есть сотни методов в классе, каждый из которых использует сотни (отдельных) классов, я мог бы превысить пространство с постоянным пулом.)
Ответы
Ответ 1
Правильно ли вы заключаете, что это означает, что один класс не может знать о существовании более чем 64 тыс. других, так как с ними невозможно ссылаться?
Я думаю, что ты прав. И не забывайте, что есть постоянные записи пула для других вещей; например все имена классов классов и полей, а также все его литералы.
Если нужно было сослаться на это много, что нужно делать - делегировать работу нескольким классам, каждый из которых может иметь свои собственные < 64k взаимодействия?
Я так думаю.
Однако я не уверен, что эта проблема будет реализована на практике. Трудно представить себе класс, который должен непосредственно взаимодействовать с этим множеством других классов... если генератор кода не игнорирует структуру исходного кода.
Ответ 2
Похоже, ваша проблема может быть решена с помощью invokedynamic
. Это в основном гораздо более быстрая форма отражения, предназначенная для облегчения реализации динамических языков в JVM.
Если вам действительно нужно иметь дело с тысячами автоматически генерируемых классов, вы, вероятно, не хотите статически связывать все это. Просто используйте invokedynamic
. Это также имеет то преимущество, что позволяет отложить некоторое генерирование кода до времени выполнения.
Обратите внимание, что вам по-прежнему нужна постоянная запись пула для каждого динамического метода, вызываемого классом, но вам больше не нужно ссылаться на фактический класс и методы, вызываемые. Фактически, вы можете создавать их по требованию.