Подтвердить что ты не робот

Любой способ "перезагрузить" JVM?

Есть ли способ перезагрузить JVM? Как и на самом деле не выходить, а закрывать и перезагружать все классы, а запускать main сверху?

4b9b3361

Ответ 1

Лучше всего, наверное, запустить java-интерпретатор в цикле и просто выйти. Например:

#!/bin/sh
while true
do
    java MainClass
done

Если вы хотите полностью перезагрузиться или завершить работу, вы можете проверить статус выхода:

#!/bin/sh
STATUS=0
while [ $STATUS -eq 0 ]
do
    java MainClass
    STATUS=$?
done

В программе java вы можете использовать System.exit(0), чтобы указать, что вы хотите "перезагрузить компьютер" и System.exit(1), чтобы указать, что вы хотите остановить и остановиться.

Ответ 3

Не настоящая "перезагрузка", но:

Вы можете создать свой собственный загрузчик классов и загрузить с него все свои классы (кроме бутстрапа). Затем, когда вы хотите "перезагрузить", убедитесь, что вы выполните следующее:

  • Завершите все темы, которые вы открыли, и используете ваши классы.
  • Утилизируйте любое созданное окно/диалог/апплет (приложение пользовательского интерфейса).
  • Закройте/удалите любые другие ресурсы GC root/OS с голодным ресурсом (соединения с базой данных и т.д.).
  • Отбросьте свой настраиваемый загрузчик классов, создайте еще один экземпляр и перезагрузите все классы. Вероятно, вы можете оптимизировать этот шаг, предварительно обработав классы из файлов, чтобы вам больше не приходилось обращаться к кодовой базе.
  • Вызовите основную точку входа.

Эта процедура используется (в некоторой степени) при работе с "горячей заменой" веб-серверов на веб-серверах.

Обратите внимание, что статические члены класса и "глобальные" объекты JVM (те, к которым обращается корень GC, который не находится под вашим контролем) будут оставаться. Например, Locale.setLocale() воздействует на статический член в Locale. Поскольку класс Locale загружается загрузчиком системного класса, он не будет "перезапущен". Это означает, что старый объект Locale, который использовался в Locale.setLocale(), будет доступен после этого, если он явно не очищен.

Еще один маршрут, который нужно предпринять, - это инструменты классов. Однако, поскольку я мало знаю об этом, я не решаюсь советоваться.

Объяснение о горячем развертывании с некоторыми примерами

Ответ 4

Если вы работаете на сервере приложений, они обычно поставляются со встроенными механизмами быстрого развертывания, которые будут перезагружать все классы в вашем приложении (веб-приложение, корпоративное приложение) при его повторном развертывании.

В противном случае вам придется искать коммерческие решения. Java Rebel (http://www.zeroturnaround.com/javarebel/) является одним из таких параметров.

Ответ 5

AFAIK нет такого пути.

Обратите внимание, что если бы был способ сделать это, он сильно зависел бы от текущего загруженного кода, чтобы должным образом освободить все удерживаемые ресурсы, чтобы обеспечить изящный перезапуск (подумайте о файлах, соединениях сокета/tcp/http/базы данных, потоки и т.д.).

Некоторые приложения, такие как Jboss AS, захватывают Ctrl + C на консоли и обеспечивают изящное завершение работы, закрывая все ресурсы, но это код приложения, а не JVM.

Ответ 6

Я делаю что-то подобное с помощью JMX, я буду "выгружать" модуль с помощью JMX и затем "перезагружать" его. За кулисами я уверен, что они используют другой загрузчик классов.

Ответ 7

Ну, у меня в настоящее время это, он отлично работает и полностью независим от ОС. Единственное, что должно работать: выполнение java-процесса без какого-либо пути/и т.д., Но я думаю, что это также можно устранить.

Маленькие фрагменты кода - все из stackoverflow, кроме RunnableWithObject и restartMinecraft():)

Вам нужно вызвать его так:

restartMinecraft(getCommandLineArgs());

Итак, что он в основном делает:

  • Создает новый процесс и сохраняет его в переменной p
  • Делает два экземпляра RunnableWithObject и заполняет объект процесса в их значение данных, затем запускает два потока, они просто печатают inputStream и errorStream, когда у него есть доступные данные, пока процесс не будет завершен.
  • Ожидает завершения процесса.
  • выводит отладочное сообщение о выходе процесса
  • Завершает с выводом значение процесса (не обязательно)

И да, это прямо из моего проекта minecraft:)

Код:

Метод Tools.isProcessExited():

public static boolean isProcessExited(Process p) {
    try {
        p.exitValue();
    } catch (IllegalThreadStateException e) {
        return false;
    }
    return true;
}

Инструмент Tools.restartMinecraft():

    public static void restartMinecraft(String args) throws IOException, InterruptedException {
//Here you can do shutdown code etc
        Process p = Runtime.getRuntime().exec(args);
        RunnableWithObject<Process> inputStreamPrinter = new RunnableWithObject<Process>() {

            @Override
            public void run() {
                // TODO Auto-generated method stub
                while (!Tools.isProcessExited(data)) {
                    try {
                        while (data.getInputStream().available() > 0) {
                            System.out.print((char) data.getInputStream().read());
                        }
                    } catch (IOException e) {
                    }
                }
            }
        };
        RunnableWithObject<Process> errorStreamPrinter = new RunnableWithObject<Process>() {

            @Override
            public void run() {
                // TODO Auto-generated method stub
                while (!Tools.isProcessExited(data)) {
                    try {
                        while (data.getErrorStream().available() > 0) {
                            System.err.print((char) data.getErrorStream().read());
                        }
                    } catch (IOException e) {
                    }
                }
            }
        };

        inputStreamPrinter.data = p;
        errorStreamPrinter.data = p;

        new Thread(inputStreamPrinter).start();
        new Thread(errorStreamPrinter).start();
        p.waitFor();
        System.out.println("Minecraft exited. (" + p.exitValue() + ")");
        System.exit(p.exitValue());
    }

Инструмент Tools.getCommandLineArgs():

public static String getCommandLineArgs() {
    String cmdline = "";
    List<String> l = ManagementFactory.getRuntimeMXBean().getInputArguments();
    cmdline += "java ";
    for (int i = 0; i < l.size(); i++) {
        cmdline += l.get(i) + " ";
    }
    cmdline += "-cp " + System.getProperty("java.class.path") + " " + System.getProperty("sun.java.command");

    return cmdline;
}

Aaaaand, наконец, класс RunnableWithObject:

package generic.minecraft.infinityclient;

public abstract class RunnableWithObject<T> implements Runnable {
    public T data;
}

Удачи:)

Ответ 8

Это легко в JavaX: вы можете использовать стандартные функции nohupJavax() или рестарт().