Невозможно использовать профилирование JVisualVM для Tomcat7, работающего как служба в Windows7

Я пытаюсь профилировать сервлет, работающий в Apache Tomcat (7.0.34), как службу в Windows 7 (64-разрядная версия), используя JVisualVM (JDK 1.7.0-06, 64-разрядная версия), работающую локально.

Первоначально у меня была проблема с тем, что Tomcat не отображался в списке локальных приложений из-за отличающейся ошибки/функции свойства «java.io.tmp», но я работал над этим, как советовали в нескольких сообщениях на этом форуме.

Однако, хотя процесс Tomcat теперь отображается в списке локальных приложений как «Локальное приложение», когда я открываю процесс, вкладки «Монитор», «Потоки», «Сэмплер» или «Профиль» отсутствуют — только вкладка «Обзор», для которой аргументы JVM и подраздел «Свойства системы» -tabs показывает страшное сообщение «не поддерживается для этого jvm».

Я дважды проверил следующие пункты:

  • что и Tomcat, и JVisualVM используют одну и ту же версию Java, просматривая свойства JVM в JVisualVM (используя соединение JMX для Tomcat)
  • что и Tomcat, и JVisualVM имеют один и тот же путь «java.io.tmp», просматривая свойства системы в JVisualVM (снова используя соединение JMX для Tomcat) И просматривая фактический каталог TMP/TEMP и подтверждая, что файлы PID для обоих существует
  • что файловая система NTFS
  • что у пользователя Windows нет подчеркивания в имени (Примечание: у пользователя есть точка в имени, поскольку мы используем сетевые логины в форме «имя.фамилия», однако у меня нет проблем с просмотром других приложений Java в JVisualVM так что не думаю, что это проблема)
  • что и Tomcat, и JVisualVM выполняются как один и тот же пользователь Windows, просматривая процессы в диспетчере задач

Пара заключительных моментов:

  • Мне нужно профилировать сервлет, поэтому использования JMX недостаточно.
  • Я смог профилировать на машине с Windows XP (Java 7, Tomcat 7 в качестве службы), так что это будет похоже на Windows 7 / 64-битную вещь?

Если кто-то имел и решил эту проблему, очевидно, решение будет высоко оценено. Однако было бы полезно просто знать, используют ли другие люди ту же конфигурацию — 64-разрядную версию Windows 7, 64-разрядную версию Java 7, Tomcat 7, работающий как службу — успешно.

Обновление: вместо того, чтобы работать как служба, я запустил Tomcat с помощью пакетного файла, и все заработало отлично: что насчет работы как службы?


person Mr Anderson    schedule 29.01.2013    source источник
comment
Просто чтобы вы знали, что вы не сумасшедший, у меня была такая же проблема с другими контейнерами сервлетов. Обычно я запускаю Sysinternals Process Explorer, смотрю на столбец командной строки (обозреватель процессов Win по умолчанию ограничен 255 символами), выполняю его из командной строки и подключаю VisualVM.   -  person Justin Garrick    schedule 14.02.2013
comment
Под каким пользователем Windows работает ваша служба Tomcat? Это может иметь значение. Попробуйте запустить VisualVM от имени того же пользователя, от имени которого работает служба Tomcat.   -  person JoshDM    schedule 15.02.2013


Ответы (4)


Как уже было сказано в моем предыдущем комментарии. Думаю, простой ответ: это невозможно. Чтобы реализовать связь между jconsole/jvisualvm и контролируемым процессом, Java использует файлы с отображением памяти. В конце концов, все сводится к определенному вызову Windows API, который дает сбой из-за функции «Усиление служб Windows» [1], добавленной в Windows Vista и, конечно же, существующей в Windows 7 и более поздних версиях.

Неудачный вызов относится к функции OpenFileMapping, как видно из строки 1402 perfMemory_windows.cpp [2]. Во время моих экспериментов метод вызывается с аргументом вида «hsperfdata_[имя пользователя]_[идентификатор процесса]». Как более подробно описано в объяснении Microsoft различий, вызванных усилением защиты службы (см. [3]), связь не будет работать, если не используется префикс имени: «Если пользовательское приложение [...] синхронизируется со службой путем создания или открытия объекты с префиксом Local\ (или без префикса, который по умолчанию имеет значение Local), приложение больше не работает должным образом».

Если кто-то хочет посмотреть сам. Вы можете использовать инструмент Logger [4], входящий в состав инструментов отладки Windows, для отслеживания вызовов API.

Также очень удобен Sysinternals Process Explorer, так как он показывает полные имена, используемые для отображаемых в память файлов, с помощью функции «Найти дескриптор или DLL...». Просто найдите дескрипторы, содержащие «hsperf».

В качестве примечания: обходной путь для удаления или иного вмешательства во временный каталог, содержащий данные hsperf, сводится к тому факту, что регистр имени пользователя, используемого отслеживаемым процессом, и процесс мониторинга должны быть согласованы. Но вместо изменения временного каталога вы также можете легко изменить переменную среды USERNAME, используемую процессом мониторинга. Вы также можете увидеть, как он используется, в строке 272 perfMemory_windows.cpp [2].

[1] http://technet.microsoft.com/en-us/library/cc507844.aspx#EHF

[2] http://hg.openjdk.java.net/jdk7/hotspot-rt/hotspot/file/5dce25362b8a/src/os/windows/vm/perfMemory_windows.cpp

[3] http://msdn.microsoft.com/en-us/windows/hardware/gg463353.aspx

[4] http://msdn.microsoft.com/en-us/library/windows/hardware/ff560123(v=vs.85).aspx

person Christian K.    schedule 27.01.2014

Вы почти сделали это «Вместо того, чтобы работать как служба, я запустил Tomcat с помощью пакетного файла, и все работало отлично: что делать с запуском как службы». Остался единственный шаг — запустить JVisualVM как услуга :)

Обратитесь к этому

https://blogs.oracle.com/nbprofiler/entry/monitoring_java_processes_running_as

Поскольку можно профилировать только процессы Java, работающие под тем же пользователем, что и VisualVM, единственный способ профилировать службу Windows (которая по умолчанию запускается под системной учетной записью) — запустить саму VisualVM как службу Windows. Обратите внимание, что этот подход не работает в Windows Vista из-за ограничений безопасности, которые по умолчанию не позволяют службам отображать какой-либо пользовательский интерфейс.

Другой вариант — запустить CMD.EXE как локальную систему, см. ниже.

http://vicevoice.blogspot.in/2009/09/vaas-visualvm-as-service.html

person Manish Singh    schedule 18.02.2013
comment
(& JoshDM) - Спасибо за ответы, однако я убедился, что служба работает от имени пользователя, под которым я входил в систему (см. последнюю точку дважды проверенных элементов в исходном сообщении ;-). Также обратите внимание, что я смог заставить все работать на XP. Один момент, о котором я не упомянул в посте, заключался в том, что я также пробовал запускать VisualVM в качестве администратора — и это тоже не принесло мне удовольствия. Однако я попробую запустить VisualVM как службу и дам вам знать. Спасибо еще раз - person Mr Anderson; 25.02.2013
comment
Кажется, что запуск cmd в качестве локальной системы (или, по крайней мере, как описано в ссылке в этой ссылке!) Не работает в Windows 8. Исходная статья написана в 2004 году, и я полагаю, что с тех пор все изменилось. Это выглядит похоже, за исключением того, что я получаю предупреждение о том, что type=interact устарел - person JonnyRaa; 25.07.2014

Разве вы не можете просто подключиться по сети, т.е. запустить JVM с

 java 
  -Dcom.sun.management.jmxremote
  -Dcom.sun.management.jmxremote.port=1234 
  -Dcom.sun.management.jmxremote.local.only=false 
  -Dcom.sun.management.jmxremote.authenticate=false 
  -Dcom.sun.management.jmxremote.ssl=false 
  -jar my.jar`

и создайте в инструменте сетевое подключение к localhost:1234

person Kire Haglin    schedule 27.01.2014

Мне также было бы любопытно, есть ли у кого-нибудь решение для Windows 7. Как было отмечено, трюк с запуском VisualVM в качестве службы не работает в Vista, и я предполагаю, что те же функции безопасности не позволяют ему работать в Win 7.

Единственное решение, которое у меня есть, — настроить ваш сервер приложений (Tomcat) как службу, чтобы при перезагрузке сервера он работал и был доступен. Затем вручную остановите службу и запустите сервер приложений (Tomcat) из командной строки и подключитесь к VisualVM. Тогда у вас есть хороший мониторинг, пока сервер не перезагружен.

person Mithel    schedule 15.07.2013
comment
Просто как дополнительное замечание, почему использование jconsole/jvisualvm вместе со службами Windows стало сложнее в Windows Vista и более поздних версиях. Это связано с добавлением новой функции под названием Усиление служб Windows [1]. Я предполагаю, что это как-то связано с механизмами изоляции сеанса, поскольку jconsole/jvisualvm полагаются на локальные механизмы IPC (файл с отображением общей памяти или именованный канал), которые должны пересекать границы сеанса. [1] technet.microsoft.com/en-us/library/cc507844 .aspx#EHF - person Christian K.; 27.01.2014