Кен Арнольд Джеймс Гослинг

Вид материалаДокументы

Содержание


Глава 14СИСТЕМНОЕ ПРОГРАММИРОВАНИЕ
14.1. Стандартный поток ввода/вывода
14.2. Управление памятью
14.3. Системные свойства
String defaultValue)
Boolean.getBoolean(String name)
Подобный материал:
1   ...   68   69   70   71   72   73   74   75   ...   81

Глава 14
СИСТЕМНОЕ ПРОГРАММИРОВАНИЕ


Глендаур: Я духов вызывать могу из бездны.
Хотспер: И я могу, и каждый это может,
Вопрос лишь, явятся ль они на зов.
Вильям Шекспир, “Генрих IV”, перевод Е. Бируковой

В этой главе рассказано, как работать с общими функциями runtime-системы Java и операционной системы. К ним относятся: определение системных свойств, математические вычисления, запуск других программ, управление памятью, отсчет времени. Эти функции предоставляются четырьмя классами Java:
  • Класс Runtime описывает состояние runtime-системы Java. Объект этого класса отвечает за доступ к функциям времени выполнения — например, управлению сборщиком мусора и прекращением работы.
  • Класс Process представляет выполняемый процесс, созданный вызовом метода Runtime.exec.
  • Класс System содержит статические методы для работы с состоянием системы в целом. Некоторые методы System оперируют с текущим runtime-контекстом.

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

14.1. Стандартный поток ввода/вывода


Вы можете осуществлять стандартные операции ввода/вывода с помощью трех системных потоков, которые являются статическими полями класса System,— System.in, System.out и System.err:

public static InputStream in

Стандартный входной поток для чтения символьных данных.

public static OutputStream out

Стандартный выходной поток для вывода сообщений.

public static PrintStream err

Стандартный поток для вывода сообщений об ошибках. Пользователи часто перенаправляют стандартный вывод программы в файл, однако приложение при этом должно иметь возможность вывести сообщение об ошибке так, чтобы пользователь его увидел. Поток err предназначен для тех сообщений об ошибках, которые не перенаправляются вместе со стандартным выводом. Потоки out и err являются объектами класса PrintStream, поэтому для вывода сообщений в err используются те же методы, что и для out.

14.2. Управление памятью


Хотя Java не позволяет явно уничтожать ненужные объекты, вы можете непосредственно вызвать сборщик мусора, используя метод gc класса Runtime. Класс Runtime также содержит метод runFinalization для вызова ожидающих блоков завершения (finalizers). Класс Runtime содержит два метода для вывода информации о состоянии памяти:

public long freeMemory()

Возвращает примерное количество свободных байтов системной памяти.

public long totalMemory()

Возвращает общее количество байтов системной памяти.

Класс System содержит статические методы gc и runFinalization, которые вызывают соответствующий метод для текущего runtime-контекста.

Не исключено, что метод Runtime.gc не сможет освободить дополнительную память за счет избавления от “мусора” — его может и не быть, к тому же не все сборщики мусора могут находить ненужные объекты по требованию. Тем не менее перед созданием большого количества объектов (особенно в приложениях, критических по времени, на работе которых могут отрицательно сказаться накладные расходы по сборке мусора) все же стоит вызвать метод gc. Он приносит двойную пользу: вы начинаете работу с максимальным объемом свободной памяти и сокращаете вероятность вызова сборщика мусора во время выполнения программы. Следующий метод освобождает всю возможную память:

public static void fullGC() {

Runtime rt = Runtime.getRuntime();

long isFree = rt.freeMemory();

long wasFree;

do {

wasFree = isFree;

rt.gc();

isFree = rt.freeMemory();

} while (isFree >> wasFree);

rt.runFinalization();

}

Данный метод в цикле вызывает gc, при этом объем свободной памяти freeMemory увеличивается до определенного предела, после достижения которого дальнейшие вызовы gc, скорее всего, ни к чему не приведут. Затем мы обращаемся к runFinalization, чтобы немедленно выполнить все завершающие действия, не позволяя сборщику мусора отложить их на потом.

Обычно вам незачем использовать runFinalization, поскольку методы finalize вызываются сборщиком мусора асинхронно. Однако при некоторых обстоятельствах (например, при нехватке ресурса, освобождаемого методом finalize) вынужденное исполнение всех возможных завершающих действий способно принести пользу. Конечно, нет никакой гарантии, что ожида-ющие завершения объекты используют данный ресурс, так что вызов run Finalization может оказаться бесполезным.

14.3. Системные свойства


Существует ряд системных свойств, которые хранятся внутри класса System в виде объекта класса Properties. Они определяют системное окружение и используются классами, которым необходима соответствующая информация. Например, приведем распечатку свойств одной системы:

#System properties

#Tue Feb 27 19:45:22 EST 1996

java.home=/lab/east/tools/java/java

java.version=1.0.1

file.separator=/

line.separator=\n

java.vendor=Sun Microsystem Inc.

user.name=arnold

os.arch=sparc

os.name=Solaris

java.vendor.url=om/

user.dir=/vob/java_prog/src

java.class.path=.:./classes:/home/arnold/java/lib/

classes.zip:/home/arnold/java/classes

java.class.version=45.3

os.version=2.x

path.separator=:

user.home=/home/arnold

Все перечисленные выше свойства определены во всех системах, хотя их значения, конечно же, меняются. Некоторые из них применяются стандартными пакетами Java. Например, класс File использует свойство file.separator для построения и анализа путей к файлам. Программисты тоже могут задействовать эти свойства. Следующий метод ищет файл конфигурации в личной папке пользователя:

public static File personalConfig(String fileName) {

String home = System.getPropety("user.home");

if (home == null)

return null;

else

return new File(home, fileName);

}

Ниже перечислены все методы класса System, которые служат для работы с системными свойствами:

public static Properties getProperties()

Возвращает объект класса Properties, представляющий системные свойства.

public static void setProperties(Properties props)

Задает системные свойства, используя для этого заданный объект класса Properties.

public static String getProperty(String key)

Возвращает текущее значение системного свойства, заданного в виде строки key. Эквивалентно

System.getProperties().getProperty(key);

public static String getProperty(String key,

String defaultValue)

Возвращает текущее значение системного свойства, заданного в виде строки key. Если оно не определено, возвращается defaultValue. Эквивалентно

System.getProperties().getProperty(key, def);

Значения свойств хранятся в виде строк, однако некоторые строки представляют другие типы — например, целые или логические. Существуют специальные методы, которые являются статическими методами соответствующих классов-оболочек, для чтения свойств и преобразования их в значения примитивных типов. Каждый из таких методов получает строковый параметр с именем свойства, интересующего программиста. Некоторые методы имеют и второй параметр (обозначенный ниже как def) со значением по умолчанию, которое возвращается в том случае, если свойство с данным именем не найдено. Методы, в которых этот параметр отсутствует, в этом случае возвращают объект, содержащий 0 для числового типа или false — для логического. Все эти методы преобразуют значения в стандартный для Java формат примитивного типа.

public static boolean Boolean.getBoolean(String name)

public static Integer Integer.getInteger(String name)

public static Integer Integer.getInteger(String name, int def)

public static Long Long.getLong(String nm)

public static Long Long.getLong(String nm, long def)

Метод getBoolean отличается от других тем, что он возвращает логическое значение (boolean) вместо объекта класса Boolean. Если свойство не найдено, getBoolean передает false.