jmap - стандартная утилита java, которую вы можете использовать для сбора дампов и статистики кучи. Я не могу сказать, какой протокол используется jmap для подключения к JVM для получения этой информации, и неясно, доступна ли эта информация для программы, запущенной в JVM напрямую (хотя я уверен, что программа может запросить JVM через некоторый сокет, чтобы получить эту информацию).
JVM TI - это интерфейс инструмента, используемый кодом C, и он имеет довольно полный доступ к событиям JVM, но это код C, а не напрямую доступный JVM. Возможно, вы могли бы написать C lib, а затем интерфейс с ним, но нет ничего из этого.
Существует несколько JMX MBeans, но я не думаю, что любой из них предоставляет фактический счет объекта. Вы можете получить статистику памяти из них (это то, что использует JConsole). Изучите классы java.lang.management.
Если вы хотите быстро (легко реализовать, не обязательно быстрый результат, так как jmap занимает некоторое время), я бы отменил запуск jmap, и просто прочитайте полученный файл.
Одна из хороших вещей [приблизительно 110] - то, что можно выполнить ее как подпроцесс и проанализировать вывод.
Мы делаем это в нашем сценарии развертывания - работы как очарование.
Это работает на dlls, заблокированный другими процессами. Эта стандартная программа не узнает, например, что текстовый файл заблокирован wordprocess.
C#:
using System.Management;
using System.IO;
static class Module1
{
static internal ArrayList myProcessArray = new ArrayList();
private static Process myProcess;
public static void Main()
{
string strFile = "c:\\windows\\system32\\msi.dll";
ArrayList a = getFileProcesses(strFile);
foreach (Process p in a) {
Debug.Print(p.ProcessName);
}
}
private static ArrayList getFileProcesses(string strFile)
{
myProcessArray.Clear();
Process[] processes = Process.GetProcesses;
int i = 0;
for (i = 0; i <= processes.GetUpperBound(0) - 1; i++) {
myProcess = processes(i);
if (!myProcess.HasExited) {
try {
ProcessModuleCollection modules = myProcess.Modules;
int j = 0;
for (j = 0; j <= modules.Count - 1; j++) {
if ((modules.Item(j).FileName.ToLower.CompareTo(strFile.ToLower) == 0)) {
myProcessArray.Add(myProcess);
break; // TODO: might not be correct. Was : Exit For
}
}
}
catch (Exception exception) {
}
//MsgBox(("Error : " & exception.Message))
}
}
return myProcessArray;
}
}
VB.Net:
Imports System.Management
Imports System.IO
Module Module1
Friend myProcessArray As New ArrayList
Private myProcess As Process
Sub Main()
Dim strFile As String = "c:\windows\system32\msi.dll"
Dim a As ArrayList = getFileProcesses(strFile)
For Each p As Process In a
Debug.Print(p.ProcessName)
Next
End Sub
Private Function getFileProcesses(ByVal strFile As String) As ArrayList
myProcessArray.Clear()
Dim processes As Process() = Process.GetProcesses
Dim i As Integer
For i = 0 To processes.GetUpperBound(0) - 1
myProcess = processes(i)
If Not myProcess.HasExited Then
Try
Dim modules As ProcessModuleCollection = myProcess.Modules
Dim j As Integer
For j = 0 To modules.Count - 1
If (modules.Item(j).FileName.ToLower.CompareTo(strFile.ToLower) = 0) Then
myProcessArray.Add(myProcess)
Exit For
End If
Next j
Catch exception As Exception
'MsgBox(("Error : " & exception.Message))
End Try
End If
Next i
Return myProcessArray
End Function
End Module
У меня возникли проблемы с решением Стефана . Ниже приведена измененная версия, которая, кажется, работает хорошо.
using System;
using System.Collections;
using System.Diagnostics;
using System.Management;
using System.IO;
static class Module1
{
static internal ArrayList myProcessArray = new ArrayList();
private static Process myProcess;
public static void Main()
{
string strFile = "c:\\windows\\system32\\msi.dll";
ArrayList a = getFileProcesses(strFile);
foreach (Process p in a)
{
Debug.Print(p.ProcessName);
}
}
private static ArrayList getFileProcesses(string strFile)
{
myProcessArray.Clear();
Process[] processes = Process.GetProcesses();
int i = 0;
for (i = 0; i <= processes.GetUpperBound(0) - 1; i++)
{
myProcess = processes[i];
//if (!myProcess.HasExited) //This will cause an "Access is denied" error
if (myProcess.Threads.Count > 0)
{
try
{
ProcessModuleCollection modules = myProcess.Modules;
int j = 0;
for (j = 0; j <= modules.Count - 1; j++)
{
if ((modules[j].FileName.ToLower().CompareTo(strFile.ToLower()) == 0))
{
myProcessArray.Add(myProcess);
break;
// TODO: might not be correct. Was : Exit For
}
}
}
catch (Exception exception)
{
//MsgBox(("Error : " & exception.Message))
}
}
}
return myProcessArray;
}
}
ОБНОВЛЕНИЕ
Если вы просто хотите знать, какие процессы блокируют конкретную DLL, вы можете выполнить и проанализировать вывод tasklist / m YourDllName .dll
. Работает на Windows XP и новее. См.
Вызвать Win32 из C # очень сложно.
Вы должны использовать инструмент Handle.exe .
После этого ваш код C # должен быть следующее:
string fileName = @"c:\aaa.doc";//Path to locked file
Process tool = new Process();
tool.StartInfo.FileName = "handle.exe";
tool.StartInfo.Arguments = fileName+" /accepteula";
tool.StartInfo.UseShellExecute = false;
tool.StartInfo.RedirectStandardOutput = true;
tool.Start();
tool.WaitForExit();
string outputTool = tool.StandardOutput.ReadToEnd();
string matchPattern = @"(?<=\s+pid:\s+)\b(\d+)\b(?=\s+)";
foreach(Match match in Regex.Matches(outputTool, matchPattern))
{
Process.GetProcessById(int.Parse(match.Value)).Kill();
}