Как отражение влияет на пермский размер?

Даже если бы Вы не хотели на самом деле редактирование в VS, Вы могли бы создать проект там и отредактировать файлы в другом редакторе.

9
задан Suraj Chandran 1 December 2009 в 12:22
поделиться

4 ответа

Постоянное пространство будет расти, когда вы выполните код, который загружает новые классы или интернализирует строки . Классы отражения обязательно должны быть загружены. Я не уверен, что API отражения в значительной степени использует внутренние строки, но это не должно быть сложно выяснить.

Например, для метода getDeclaredMethod (String name, Class ... parameterTypes) параметр имени будет встроен.

Этот фрагмент прекрасно заполнит свободное пространство:

Random random = new Random();
while(true){
    try {
        X.class.getDeclaredMethod(toBinaryString(random.nextLong()));
    } catch (Exception e) {
    }
}

альтернативный текст http://img4.imageshack.us/img4/9725/permgen.jpg

в реальном приложении это не будет иметь никакого значения.

7
ответ дан 4 December 2019 в 13:47
поделиться

Отражение может генерировать классы в зависимости от реализации. Например, вам может потребоваться использовать артефакт отражения тысячи раз, прежде чем он будет скомпилирован в байт-код.

Как всегда, совет: профилируйте свой код в реалистичных ситуациях.

3
ответ дан 4 December 2019 в 13:47
поделиться

Я не совсем уверен, что понимаю вопрос, но классы Java уже включают в себя все, что необходимо для их отражения. Файл .class не меняется в зависимости от того, как он используется.

Редактировать 1: Предоставление некоторых более конкретных примеров, чтобы лучше различать тип «отражения», о котором мы говорим.

Пример:

class Foo {
    public void bar() {
        System.out.println( "Hello, world." );
    }
}

// Conventional calling
Foo f = new Foo();
foo.bar();

// Reflection based callling
Class fooClass = Class.forName( "Foo" );
Method m = fooClass.getMethod( "bar", null );
Object f = fooClass.newInstance();
m.invoke( m, null );     

В обычном вызывающий случай, будет загружен Foo.class и любые его прямые зависимости класса. бар будет выполнен. Строки «Foo» и «bar» уже будут интернированы как часть вызывающего класса, потому что байтовый код использует строки для разрешения классов и методов во время выполнения. (на самом деле «bar» будет полной сигнатурой метода, поэтому на самом деле длиннее, чем просто «bar»)

В случае отражения происходит то же самое. Единственный загруженный дополнительный класс - это Method.class. Это должно быть единственным фактором, влияющим на размер разрешения.

Последний случай влияет на производительность. Поиск метода относительно дорог, поэтому рекомендуется кэшировать объекты Method, когда это возможно. Вызов дополнительного метода для вызова имеет небольшое влияние на производительность, поскольку это дополнительный вызов метода. У точки доступа возникнут проблемы с оптимизацией через этот вызов ... по крайней мере, больше, чем обычно. JITing происходит точно так же.

Edit 2: Обратите внимание на некоторые дополнительные объекты, которые загружаются во время отражения ...

java.lang.Class будет создавать и кэшировать объекты Method (или объекты поля и т.д.) при доступе. Они кэшируются в SoftReference и поэтому будут восстановлены, если этого требует использование памяти.

Однако инициализация этих объектов означает, что могут быть дополнительные интерн ' ed строки, загруженные виртуальной машиной для поддержки создания этих объектов Method. Я предполагаю, что эти строки, вероятно, уже были частью постоянного пула рефлексивного класса, но возможно, что это не так. В любом случае, это однократное обращение к каждому методу, классу, полю, классу и т. Д. Получив доступ к методам, вы получите, по крайней мере, все имена этих методов интернированными. Получив доступ к полям, вы получите интернированные имена этих полей.

3
ответ дан 4 December 2019 в 13:47
поделиться

Первый ответ в основном правильный - не имеет значения, загружается ли класс «нормально» или через отражение. В любом случае он загружен. Я не могу придумать никакой разницы в интернированных строках, о которых я знаю.

Я полагаю, есть более косвенный эффект: использование отражения может привести к загрузке меньшего количества классов. Допустим, у вас есть код, который загружает один из 100 классов на основе некоторого параметра. Написав его без отражения, вы должны импортировать все 100 классов и создать экземпляр одного из них.

С отражением будет загружен только 1 класс. Без этого в момент загрузки класса с этим кодом будут загружены все 100 импортированных классов, поскольку на них есть ссылки. Таким образом, в перманентное пространство загружается больше классов.

Но это несколько надуманный пример. Если он действительно не описывает вашу ситуацию, Думаю, вы практически не заметите разницы. То есть, пока вы не убедитесь, что это нетривиально, не позволяйте этому влиять на ваши дизайнерские решения.

2
ответ дан 4 December 2019 в 13:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: