Ответ 1
Какой-то исходный код копал и кодировал сам, чтобы понять это, и вот что я узнал:
Класс Java 'Method' имеет переменную-член 'methodAccessor' типа 'MethodAccessor', которая является интерфейсом с методом 'invoke', подобным методу invoke. Методы вызова делегатов в методAccessor invoke.
Если инфляция включена (noInflation is false), этот аксессор указывает на реализацию, которая использует JNI для запуска этого Java-метода (я думаю, используя api, как GetObjectClass, GetMethodID и Call * Method). Это похоже на отправку поединков, и исполнение с JNI происходит медленно из-за этой и других причин. (Что делает JNI медленным?)
После 15 исполнений метода через отражение ('15' по умолчанию и может быть изменено), а с noInflation false, аксессуар на основе JNI создает класс "на лету" (имя динамически генерируется, например, "GeneratedMethodAccessor1" ) который также имеет метод invoke. Теперь в этом методе "invoke" он выдает первый аргумент "obj" соответствующему классу и затем вызывает на нем целевой метод. Затем он создает экземпляр этого класса и изменяет параметры methodAccessor таким образом, что каждое выполнение метода впредь делегируется этому экземпляру вместо JNI-аксессуаров. Это называется инфляцией.
Поскольку этот экземпляр представляет собой класс Java, который делегирует объект Java, делегация впредь является нормальной Java-делегией. Он никогда не переходит в JNI и, следовательно, сохраняет эти накладные расходы, плюс JITC может выполнять другую оптимизацию на нем, благодаря чему он становится эффективным.
Недостатком является то, что, если множество методов накачивается таким образом, их классы занимают пространство пермгенов и могут вызвать ошибку в памяти.
Подробнее см.
http://java.sun.com/docs/books/jni/html/fldmeth.html
http://anshuiitk.blogspot.com/2010/11/excessive-full-garbage-collection.html