Eclipse: как загрузить огромный класс/интерфейс (включая более 40000 статических полей) в фоновом потокеJAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Eclipse: как загрузить огромный класс/интерфейс (включая более 40000 статических полей) в фоновом потоке

Сообщение Anonymous »

У меня есть интерфейс примерно с 40 000 статических полей (я знаю, что он огромен), и я пытаюсь загрузить его эффективно. Обычная загрузка занимает 10 секунд и замораживает поток пользовательского интерфейса Eclipse, что неприятно для пользователя. Чтобы предотвратить зависание, я попытался загрузить интерфейс в фоновом потоке, используя следующий код:

Код: Выделить всё

var thread = new Thread(() -> {
var classLoader = My_Small_Class_Of_The_Same_Plugin.getClass().getClassLoader();
try {
classLoader.loadClass("My_Super_Big_Interface");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
});
thread.start();
Неожиданно поток пользовательского интерфейса все еще зависает. Ответственный EquinoxClassLoader зарегистрирован как «параллельный», что звучит так, как будто его можно использовать в отдельном потоке для повышения производительности.
Почему это не работает?
Есть ли способ загрузить класс/интерфейс независимо от основного потока/потока пользовательского интерфейса?
Обратите внимание: я не хочу обсуждать размер интерфейса и что его следует разделить на несколько интерфейсов или классов. К сожалению, так дано и мне приходится с этим бороться.
Редактировать 1
Я обнаружил, что существует проблема с реализацией JVM (в моем случае OpenJDK 21). Когда загрузчик классов начинает загрузку с использованием собственного метода defineClass1(ClassLoader loader, ...); (см.: OpenJDK ClassLoader.java), он приостанавливает каждый поток до тех пор, пока выполняется определение класса. Это как минимум удивительно. Еще более удивительно то, что загрузка класса размером около 1,5 МБ, который не ссылается ни на какие другие классы или интерфейсы, занимает около 10 секунд. Вот небольшой пример (1 класс + 1 интерфейс) того, как его можно воспроизвести:
  • Код: Выделить всё

    My_Super_Big_Interface
    : Поскольку интерфейс слишком велик для публикации его здесь, сгенерируйте его самостоятельно, используя следующий или собственный код:

Код: Выделить всё

     /**
* Generates a big interface with a huge number of fields.
*
* @param args
*/
public static void main(String[] args) {
var NUMBER_OF_FIELDS = 40000;
var fields = "";

for (var i = 1; i  {
var i = 1;
while (true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("\t\tLoop thread: " + i++ + ".  round: " + LocalDateTime.now());
}
}).start();
System.out.println("Loop thread started at: " + LocalDateTime.now());

// 2) start the class loading thread which pauses the other threads
var class_Loading_Thread = new Thread(() -> {
var classLoader = MainClass.class.getClassLoader();
try {
var start_Millis = System.currentTimeMillis();
System.out.println("Before class loading: " + LocalDateTime.now());

// start the loading which causes every thread to pause
classLoader.loadClass("com.test.My_Super_Big_Interface");       //  11:24:41.438144700.
[b]Может ли кто-нибудь проверить результат на своей машине?[/b] Пожалуйста, запустите код и НЕ запускайте его в режиме отладки.
[b]Может ли кто-нибудь запустить его в другой реализации JVM?[/b]
Я пытался найти ответственный код в реализации OpenJDK, начиная здесь: java.base.share.native.libjava.ClassLoader.c, но до сих пор не нашел его.
После пары тестов выяснилось, что время выполнения класса увеличивается. Загрузка определения/класса экспоненциально зависит от количества полей/членов. Например, для 20000 полей требуется 2 секунды, для 30000 – 6 секунд, для 40 000 – 10 секунд и для 65 000 – 30 секунд. 

Подробнее здесь: [url]https://stackoverflow.com/questions/79873770/eclipse-how-to-load-a-huge-class-interface-including-40000-static-fields-in[/url]
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»