Симуляция процессов ОС в java / упреждающий останов потока / classloader + имитация процесса потока - PullRequest
1 голос
/ 19 марта 2012

У меня есть пул потоков (исполнитель), который я хотел бы отслеживать на предмет чрезмерного использования ресурсов (время, когда процессор и память кажутся довольно сложными).Я хотел бы «убить» потоки, которые работают слишком долго, например, убить процесс ОС.Рабочие тратят большую часть времени на вычисления, но значительное время также тратится на ожидание операций ввода-вывода, в основном базы данных ...

Я читал об остановке потоков в java и о том, как она устарела по причинам очистки ресурсов (неправильное снятие блокировок, закрытие сокетов и файлов и т. д.).Рекомендуемый способ - периодически проверять в рабочем потоке, должен ли он остановиться, а затем выйти.Это, очевидно, предполагает, что клиентские потоки будут записываться определенным образом и что они не блокируются в ожидании некоторых внешних операций ввода-вывода.Существуют также ThreadDeth и InterruptedException, которые могут выполнять эту работу, но на самом деле они могут быть обойдены в неправильно / неправильно написанных рабочих потоках, а также у меня сложилось впечатление (хотя пока еще нет тестирования), что InterruptedException может работать некорректно в некоторых (или даже во всех) случаях, когда рабочий поток ожидает ввода-вывода.

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

Это привело меня к старой истории об изолятах и ​​/ или MVM более пяти лет назад, но, похоже, ничего не произошло на этом фронте, может быть, в java 8 или 9 ...

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

Любые рекомендации / идеи?

РЕДАКТИРОВАТЬ:

Я спрашиваю из-за общего интереса и разочарованиячто в JVM до настоящего времени не существует решений для этого (я имею в виду, что общие серверы приложений на самом деле невозможны - домены приложений или что-то подобное в .NET, похоже, решают именно такую ​​проблему).Я понимаю, что уничтожение процесса не гарантирует возврата всего состояния системы к некоторому начальному состоянию, но по крайней мере все ресурсы, такие как дескрипторы, память и процессор, освобождаются.Я думал об использовании загрузчиков классов, поскольку они могут помочь в освобождении блокировок, удерживаемых потоком, что является одной из причин, по которой Thread.stop устарел.В моей текущей ситуации единственное, что должно быть освобождено (я могу думать в настоящее время), это соединение с базой данных, которое может быть обработано отдельно / внешне (сторожевым потоком), если это необходимо .. Хотя, действительно, в моем случае Thread.stop может на самом делебыть работоспособным, я просто не люблю использовать устаревшие методы ..

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

Итак, чтобы уточнить, я спрашиваю, как, например, java люди на стороне сервера обрабатывают побочные потоки?Я подозреваю, что использование множества машин в кластере для устранения проблемы и перезапуска неправильной работы - когда приложение по крайней мере не имеет состояния ...

1 Ответ

1 голос
/ 19 марта 2012

Разница между потоком и процессом заключается в том, что поток неявно разделяет память и ресурсы, такие как сокеты и файлы (что делает обход локальной памяти потока).Процессы неявно имеют личную память и ресурсы.

Убить поток не проблема.Проблема в том, что поток с плохим поведением или даже поток с разумным поведением могут оставлять ресурсы в несогласованном состоянии.Использование загрузчика классов не поможет вам отследить это или решить проблему за вас.Для процессов проще отслеживать, какие ресурсы они используют, так как большая часть ресурсов изолирована.Даже для процессов они могут оставить блокировки, временные файлы и общие ресурсы IPC в неправильном состоянии в случае их уничтожения.

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


РЕДАКТИРОВАТЬ: Вот простая программа, которая будет тупиковой между двумя процессами или машинами, потому что в нем есть ошибка.Чтобы остановить тупики, нужно исправить код.

public static void main(String... args) throws IOException {
    switch(args.length) {
        case 1: {
            // server
            ServerSocket ss = new ServerSocket(Integer.parseInt(args[0]));
            Socket s = ss.accept();
            ObjectInputStream ois = new ObjectInputStream(s.getInputStream());
            ObjectOutputStream oos = new ObjectOutputStream(s.getOutputStream());
            // will deadlock before it gets here
            break;
        }
        case 2: {
            Socket s = new Socket(args[0], Integer.parseInt(args[1]));
            ObjectInputStream ois = new ObjectInputStream(s.getInputStream());
            ObjectOutputStream oos = new ObjectOutputStream(s.getOutputStream());
            // will deadlock before it gets here
            break;
        }
        default:
            System.err.println("Must provide either a port as server or hostname port as client");
    }
}
...