2016-08-27 13 views
2

JNA делает безумное количество мусора, когда я пытаюсь найти поддельный процесс по имени.Java JNA 4.3.0 Создает безумного мусора при поиске процесса

Вот скриншот из распределений (около 100k.sec)

enter image description here

Вот тестовый пример (используется 4.3.0 СНАПШОТ из ЮНА)

import com.sun.jna.Native; 
import com.sun.jna.platform.win32.Kernel32; 
import com.sun.jna.platform.win32.Tlhelp32; 
import com.sun.jna.platform.win32.WinDef; 
import com.sun.jna.platform.win32.WinNT; 

/** 
* Created by Jonathan on 8/26/2016. 
*/ 
public class Main { 

    public static void main(String[] args) { 
     while (true) 
      openProcess("doesntexist.exe"); 
    } 

    private static final WinDef.DWORD DWORD_ZERO = new WinDef.DWORD(0); 
    private static final Tlhelp32.PROCESSENTRY32 entry = new Tlhelp32.PROCESSENTRY32.ByReference(); 

    private static WinNT.HANDLE openProcess(String processName) { 
     WinNT.HANDLE snapshot = Kernel32.INSTANCE.CreateToolhelp32Snapshot(Tlhelp32.TH32CS_SNAPALL, DWORD_ZERO); 
     try { 
      while (Kernel32.INSTANCE.Process32Next(snapshot, entry)) { 
       String fileName = Native.toString(entry.szExeFile); 
       if (processName.equals(fileName)) 
        return Kernel32.INSTANCE.OpenProcess(WinNT.PROCESS_ALL_ACCESS, true, entry.th32ProcessID.intValue()); 
      } 
     } finally { 
      Kernel32.INSTANCE.CloseHandle(snapshot); 
     } 
     return null; 
    } 

} 

И, наконец, здесь это моментальный снимок памяти https://dl.dropboxusercontent.com/u/91292881/ShareX/2016/08/JNA%204.3.0.snapshot

+0

Сколько процессов вы создаете? Просто отслеживая код, похоже, что цикл while создает структуру 'Tlhelp32.PROCESSENTRY32' для каждого из них. –

+0

И где вы получаете 4.3.0? Последний выпуск - 4.2.2. Это сборка снимков? –

+0

Да, это сборка моментальных снимков. –

ответ

1

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

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

String fileName = Native.toString(entry.szExeFile); 

Внутренне Native.toString(char[] buf) создает new String() каждый время:

public static String toString(char[] buf) { 
    int len = buf.length; 
    for (int index = 0; index < len; index++) { 
     if (buf[index] == '\0') { 
      len = index; 
      break; 
     } 
    } 

    if (len == 0) { 
     return ""; 
    } else { 
     return new String(buf, 0, len); 
    } 
} 

Эти String объекты используются один раз для проверки равенства, а затем бросили на куче.

Поскольку основной целью создания String является проверка равенства, вы можете, вероятно, проверить равенство напрямую, используя базовый массив char[]. Преобразуйте processName в char[] и одновременно итерации по обеим массивам, для проверки равенства символов до длины processName с нулевым терминатором следующего символа entry.szExeFile.