Java-реализация функции * nix sync () без системного вызова


Я работаю над удалением всех системных вызовов из существующей базы кода Java. Мы запускаем наше приложение в коммерческом, с закрытым исходным кодом, JVM. Когда JVM делает системный вызов через getRuntime.exec () java вызывает форки всего процесса JVM, что приводит к серьезным падениям производительности. Мы работаем на платформе linux, но в идеале стараемся сделать вещи максимально портативными.

У меня возникли проблемы с заменой вызова sync (), который мы в настоящее время используем через getRuntime.метод exec (). Я знаю существует Этот метод sync() и flush(). И на основе этого поста я хочу сделать синхронизацию и промыть все открытые файловые потоки.

Моя проблема заключается в том, что у меня нет прямых знаний о том, какие файловые потоки и дескрипторы существуют. Я думал, что один из способов обойти это будет проверить папку /proc/(JVM process number)/fd, но я не могу найти хороший способ надежно получить номер процесса JVM с помощью чистой java. Я думал, что смогу достать все предметы. определенного класса (Класс FileDescriptor), но из того, что я читаю, это также неосуществимо.

Есть ли у кого-нибудь предложения о том, как дублировать вызов *nix sync() в чистой java?

1 5

1 ответ:

То, что вы делаете, - это больше, чем вызов sync. Вы пытаетесь выполнить операцию" очистить все буферы файлов и sync". У вас были бы проблемы с этим в C / C++ тоже.

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

Предположим, что ваше приложение является многопоточным и что один поток отвечает за вызов sync. Как этот поток знает, что другие потоки, которые пишут файлы, достигли согласованной точки записи файлов; т. е. что если приложение было убито и перезапущено, то (гипотетически) сброшенные файлы будут содержать логически согласованное состояние для приложения? Ответ (скорее всего) состоит в том, что он не знает. Так... на самом деле... приложение не находится в значительно лучшем положении, если оно промывает перед синхронизацией.

И есть еще одна проблема. Предположим, что поток A отвечает за flush / sync, а поток B счастливо записывает в некоторый выходной поток. Рассмотрим эту временную последовательность:

  1. поток файла flushes
  2. поток B записывает в файл
  3. поток A вызывает синхронизацию

Единственный способ избежать этого-синхронизировать поток A и блокировать все другие потоки, которые записывают в файлы ... Перед он делает флеш(Ы) и синхронизацию.

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