Как увеличить ограничение в 4096 байт / proc / pid / cmdline?

Для моих приложений Java с очень длинными путями к классам я не вижу основной класс, указанный в конце списка аргументов при использовании ps. Я думаю, это связано с ограничением размера моей системы Ubuntu на / proc / pid / cmdline. Как я могу увеличить этот лимит?


person user27635    schedule 13.10.2008    source источник
comment
Поскольку я не являюсь парнем, занимающимся Java, мне интересно, как это запустить в Windows. У XP был предел, я думаю, 2048.   -  person Camilo Martin    schedule 18.07.2014


Ответы (8)


Вы не можете изменить это динамически, ограничение жестко запрограммировано в ядре на PAGE_SIZE в fs / proc / base.c:

 274        int res = 0;
 275        unsigned int len;
 276        struct mm_struct *mm = get_task_mm(task);
 277        if (!mm)
 278                goto out;
 279        if (!mm->arg_end)
 280                goto out_mm;    /* Shh! No looking before we're done */
 281
 282        len = mm->arg_end - mm->arg_start;
 283 
 284        if (len > PAGE_SIZE)
 285                len = PAGE_SIZE;
 286 
 287        res = access_process_vm(task, mm->arg_start, buffer, len, 0);
person Robert Gamble    schedule 13.10.2008
comment
Обратите внимание, что это можно изменить, если вы хотите перекомпилировать ядро ​​для этого (см. Мой комментарий для ссылки с инструкциями). - person Jay; 14.10.2008
comment
Все, что угодно, можно изменить, если вы хотите перекомпилировать ядро, но его по-прежнему нельзя изменять динамически. - person Robert Gamble; 14.10.2008
comment
Перекомпиляция ядра похожа на переезд в новый дом, потому что предыдущий диван вам не понравился. - person Camilo Martin; 18.07.2014
comment
Это было исправлено в июне 2015 года, и этот ответ уже устарел. - person JdeBP; 22.03.2018

Для просмотра процессов Java очень полезен jps .

Это даст вам основной класс и аргументы jvm:

jps -vl | grep <pid>
person Kevin Cross    schedule 08.09.2010
comment
Для меня даже хуже. Обрезается быстро - person HaveAGuess; 05.11.2010
comment
@HaveAGuess, wfm - показывает основной класс, независимо от того, насколько неприлично длинным может быть путь к классам, что и просил OP. (При желании он также может показывать другие аргументы.) - person Greg Price; 26.07.2011
comment
У меня тоже работает, показывает все параметры для безумно длинных (более 4096 символов) командных строк Weblogic (Linux 64bit). Спасибо, Кевин! - person t0r0X; 25.04.2014
comment
Я пытаюсь jps увидеть полный путь к классам java-процессов hadoop ... по какой-то причине jps даже не покажет мне путь к классам! - person ernesto; 17.08.2014
comment
Спасибо, у меня это сработало. Мне нужно было добавить параметр -m, чтобы увидеть аргументы командной строки. - person Steve; 21.04.2017
comment
jps -lvm для меня даже лучше - m необходим для отображения аргументов командной строки (не аргументов JVM), переданных вашему main методу Java. - person javabrett; 27.10.2017

Я временно обхожу ограничение аргумента командной строки в 4096 символов для ps (или, скорее, / proc / PID / cmdline), используя небольшой скрипт для замены команды java.

Во время разработки я всегда использую распакованную версию JDK от SUN и никогда не использую установленную JRE или JDK ОС, независимо от того, Linux или Windows (например, загрузите bin вместо rpm.bin). Я не рекомендую изменять сценарий для вашей установки Java по умолчанию (например, потому что это может привести к сбою обновлений, перезаписи, возникновению проблем или ...)

Итак, предполагая, что команда java находится в /x/jdks/jdk1.6.0_16_x32/bin/java

сначала удалите фактический двоичный файл:

mv /x/jdks/jdk1.6.0_16_x32/bin/java /x/jdks/jdk1.6.0_16_x32/bin/java.orig

затем создайте скрипт /x/jdks/jdk1.6.0_16_x32/bin/java, например:

    #!/bin/bash

    echo "$@" > /tmp/java.$$.cmdline
   /x/jdks/jdk1.6.0_16_x32/bin/java.orig $@

а затем сделайте скрипт работоспособным

chmod a+x /x/jdks/jdk1.6.0_16_x32/bin/java

в случае копирования и вставки вышеуказанного убедитесь, что в /x/jdks/jdk1.6.0_16_x32/bin/java нет лишних пробелов, а #! / bin / bash - это первая строка

Полная командная строка заканчивается, например, /tmp/java.26835.cmdline, где 26835 - это PID сценария оболочки. Я думаю, что есть также некоторое ограничение оболочки на количество аргументов командной строки, не могу вспомнить, но, возможно, это было 64 КБ символов.

вы можете изменить сценарий, чтобы удалить текст командной строки из /tmp/java.PROCESS_ID.cmdline в конце

После того, как я получил командную строку, я всегда перемещаю сценарий во что-то вроде "java.script" и копирую (cp -a) фактический двоичный файл java.orig обратно в java. Я использую скрипт только тогда, когда достигаю предела 4K.

Могут быть проблемы с экранированными символами и, возможно, даже с пробелами в путях или чем-то подобным, но у меня это отлично работает.

person Community    schedule 17.08.2009
comment
Это, наверное, самый простой способ. Вы также можете установить переменную среды CLASSPATH только для этой конкретной команды или разделить необходимые пути между CLASSPATH и командной строкой. - person We Are All Monica; 14.10.2009
comment
Отличный обходной путь, чтобы увидеть полную командную строку, я тоже использовал его для javac - person stivlo; 16.12.2011
comment
Если у вас есть доступ к фактическому используемому исполняемому файлу Java (например, в Eclipse), вы можете пропустить перемещение двоичного файла и просто создать сценарий, который печатает командную строку (в файл), а затем запускает приложение Java. Убедитесь, что вы поместили сценарий в папку bin JDK. - person Barry NL; 19.09.2014

Вы можете использовать jconsole, чтобы получить доступ к исходной командной строке без ограничений по длине.

person Matt    schedule 05.08.2010
comment
он может работать и увеличивает ограничение длины, но для действительно огромной командной строки он больше не работает и обрезается (только что испытал это). - person stivlo; 16.12.2011

Можно использовать более новые дистрибутивы Linux, где это ограничение было снято, например RHEL 6.8 или новее.

"Предел длины файла / proc / pid / cmdline для команды ps был ранее жестко задан в ядре и составлял 4096 символов. Это обновление гарантирует, что длина / proc / pid / cmdline не ограничена, что особенно полезно для перечисления процессов с длинными аргументами командной строки. (BZ # 1100069) "

https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/6/html/6.8_Release_Notes/new_features_kernel.html

person riverfall    schedule 13.03.2017

Для программ на основе Java, в которых вы просто заинтересованы в проверке аргументов командной строки, полученных вашим основным классом, вы можете запустить:

jps -m
person kamstrup    schedule 26.05.2016

Я почти уверен, что если вы действительно видите усеченные аргументы в / proc / $ pid / cmdline, значит, вы на самом деле превышаете максимальную длину аргумента, поддерживаемую ОС. Насколько я могу судить, в Linux размер ограничен размером страницы памяти. См. ограничение длины ps ww для справки.

Единственный способ обойти это - перекомпилировать ядро. Если вы хотите зайти так далеко, чтобы решить эту проблему, вы можете найти этот пост полезным: "Список аргументов тоже long ": помимо аргументов и ограничений

Дополнительная ссылка:
ARG_MAX, максимальная длина аргументов для нового процесса < / а>

person Jay    schedule 13.10.2008
comment
-1. Первая часть вашего комментария неверна. В моей системе getconf ARG_MAX говорит, что ARG_MAX = 2097152 (это означает, что максимальная длина аргумента составляет 2 мегабайта). Однако /proc/$pid/cmdline усекается до PAGE_SIZE, что составляет 4096. Ваша ссылка с инструкциями НЕ охватывает эту конкретную ситуацию - я понятия не имею, вызовет ли изменение соответствующего бита в fs/proc/base.c другие проблемы. - person We Are All Monica; 14.10.2009

Возможно, вам нужен параметр w для ps. Добавьте две буквы «w» для большей производительности. Он сообщает ps игнорировать ширину линии терминала.

person caskey    schedule 13.10.2008
comment
нет, даже с ww он обрезается до 4096. Я думаю, что ps читает из / prod / pid / cmdline, который также усечен. - person user27635; 14.10.2008
comment
Просто чтобы прояснить, что сказал @Caskey с помощью Add two для увеличения вывода, это -w -w (или -ww) для неограниченной ширины вывода. - person Jay; 14.10.2008
comment
@Jay, к сожалению, кажется, не безграничен, он ограничен 4096 символами. - person AJP; 05.03.2014