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

Как узнать количество файлов, открытых в настоящее время Java-приложением?

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

Теперь, есть ли способ достоверно узнать, сколько файлов открывается процессом? Нечто такое же надежное, как просмотр ls/proc/my_pid/fd | wc -l ls/proc/my_pid/fd | wc -l изнутри JVM?

Я подозреваю, что ответ может зависеть от ОС, поэтому позвольте мне добавить, что я использую Java на Linux.

4b9b3361

Ответ 1

В Unix одним из способов является использование ManagementFactory для получения OperatingSystemMxBean и если это UnixOperatingSystemMXBean, вы можете использовать метод getOpenFileDescriptorCount().

Пример кода:

import java.lang.management.ManagementFactory;
import java.lang.management.OperatingSystemMXBean;
import com.sun.management.UnixOperatingSystemMXBean;

public class OpenFileCount{
    public static void main(String[] args){
        OperatingSystemMXBean os = ManagementFactory.getOperatingSystemMXBean();
        if(os instanceof UnixOperatingSystemMXBean){
            System.out.println("Number of open fd: " + ((UnixOperatingSystemMXBean) os).getOpenFileDescriptorCount());
        }
    }
}

Ответ 2

Если вы хотите получить номер ls /proc/my_pid/fd | wc -l в java, вы можете использовать JMX.

Когда у вас есть MBeanServerConnection, вы можете получить атрибут "OpenFileDescriptorCount". это даст вам тот же результат, что и выше ls..|wc -l.

также существует еще один атрибут "MaxFileDescriptorCount", в котором указано, что максимальное количество допустимо.

Если вы просто хотите знать значение, но не получаете его в своем коде, вы можете либо сделать свой способ ls..|wc -l, либо прочитать из jconsole (с графическим интерфейсом).

Примечание

ls /proc/my_pid/fd | wc -l

это число указывает, сколько fd было открыто вашим процессом (приложение java). например учитываются ваши бизнес файлы, также учитываются эти банки, файлы библиотек. Если вы просто хотите получить кол-во своих бизнес файлов, вам придется самостоятельно выполнить счетчик. Или, скажем, вы хотите сделать это с помощью shellscript, grep что-то, а затем wc -l

ИЗМЕНИТЬ

добавьте пример кода, но это всего лишь пример. не написанный в среде IDE, не протестированный с помощью компилятора.:)

ObjectName oName = new ObjectName("java.lang:type=OperatingSystem");
MBeanServerConnection conn ; // you should get the connection following the api, take a look the java api/ google some example
javax.management.AttributeList list = conn.getAttributes(oName, new String[]{"OpenFileDescriptorCount", "MaxFileDescriptorCount"});
for(Attribute attr: list.asList()){
    System.out.println(attr.getName() + ": " + attr.getValue());
}

Ответ 3

Ради заполнения/добавления к ответу:

Многие люди используют LSOF в Linux-системах для мониторинга файловых дескрипторов и их деталей. Однако LSOF перечисляет все виды FD (CWD, MEM), которые не возвращаются UnixOperatingSystemMXBean.getOpenFileDescriptorCount().

Подробности можно найти в http://www.ibm.com/developerworks/aix/library/au-lsof.html. Это может вызвать некоторую путаницу.

Для пояснения UnixOperatingSystemMXBean.getOpenFileDescriptorCount() показывает только дескрипторы открытых файлов приложения. Но LSOF (lsof -a -p) перечисляет другие файловые дескрипторы, открытые ядром от имени процесса.

Для отображения только FDS уровня приложения можно отфильтровать FD другого типа.

lsof -a -p yourprocid -d ^ txt, ^ mem, ^ cwd, ^ rtd, ^ DEL