Вызывать публичные методы с помощью invokespecial? - PullRequest
1 голос
/ 04 октября 2019

Как любой, кто может ответить на этот вопрос, уже знает, JVM поддерживает несколько инструкций байт-кода для вызова методов (invokevirtual, invokespecial, invokestatic, ...)

Большинство вызовов методов включенометоды экземпляра создаются с помощью invokevirtual, но частные методы и методы инициализатора вызываются с помощью invokespecial, как описано в спецификации JVM:

The difference between the invokespecial and the invokevirtual instructions is that 
invokevirtual invokes a method based on the class of the object. The invokespecial instruction 
is used to invoke instance initialization methods as well as private methods and methods of a 
superclass of the current class.

Насколько я понимаю, invokevirtual выполняет поиск в vtableразрешить метод, в то время как invokespecial, поскольку правильная реализация метода известна во время соединения, разрешается статически.

Мой вопрос: почему invokespecial не используется для вызова public методов в тех случаях, когдаконкретный класс владельца метода известен во время компиляции? Мне кажется, что избегание поиска vtable было бы желательно по соображениям эффективности. Но очевидно, что в JVM есть что-то, чего я не понимаю.

1 Ответ

3 голосов
/ 04 октября 2019

Во-первых, не так просто узнать конкретную цель вызова во время компиляции. JVM может загружать новые классы динамически и даже переопределять существующие классы во время выполнения. Открытый метод, который во время компиляции казался не виртуальным, может стать виртуальным во время выполнения.

Вы правы, что поиск в vtable может повлиять на производительность. Тем не менее, invokevirtual байт-код вовсе не подразумевает поиск в vtable.

Например, HotSpot JVM делает все возможное для девиртуализации вызовов методов. Он использует анализ иерархии классов и профили типов времени выполнения для перевода invokevirtual для прямых вызовов или, что еще лучше, для встроенных «виртуальных» методов непосредственно в сайт вызовов. Только настоящие мегаморфные сайты вызовов (которые имеют 3 или более целей во время выполнения) подвергаются поиску vtable.

Тем не менее, в современных JVM нет разницы в производительности между invokespecial и invokevirtual, когда целевой методна самом деле не виртуальный.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...