对于类路径很长的 Java 应用程序,在使用 ps 时,我看不到 arg 列表末尾附近指定的主类。我认为这源于我的 Ubuntu 系统对 /proc/pid/cmdline 的大小限制。我怎样才能增加这个限制?
8 回答
您不能动态更改它,限制在内核中硬编码为 fs/proc/base.c 中的 PAGE_SIZE:
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);
我暂时绕过 ps(或者更确切地说 /proc/PID/cmdline)的 4096 个字符的命令行参数限制是通过使用一个小脚本来替换 java 命令。
在开发过程中,我总是使用 SUN 的未打包 JDK 版本,并且从不使用已安装的 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 是 shell 脚本的 PID。我认为命令行参数的数量也有一些 shell 限制,不记得但可能是 64K 字符。
您可以更改脚本以在末尾从 /tmp/java.PROCESS_ID.cmdline 中删除命令行文本
获得命令行后,我总是将脚本移动到类似“java.script”的位置,然后将实际的二进制 java.orig 复制 (cp -a) 回 java。我只在达到 4K 限制时才使用脚本。
转义字符可能存在问题,甚至路径中的空格等可能存在问题,但对我来说效果很好。
您可以使用jconsole
不受所有长度限制来访问原始命令行。
可以使用更新的 linux 发行版,其中删除了此限制,例如 RHEL 6.8 或更高版本
“ps 命令的 /proc/pid/cmdline 文件长度限制以前在内核中硬编码为 4096 个字符。这次更新确保 /proc/pid/cmdline 的长度不受限制,这对于列出进程特别有用带有长的命令行参数。(BZ#1100069)"
对于只对检查主类获得的命令行参数感兴趣的基于 Java 的程序,您可以运行:
jps -m
我很确定,如果您实际上看到 /proc/$pid/cmdline 中的参数被截断,那么您实际上超出了操作系统支持的最大参数长度。据我所知,在 Linux 中,大小仅限于内存页面大小。请参阅“ps ww”长度限制以供参考。
解决这个问题的唯一方法是重新编译内核。如果您有兴趣解决这个问题,那么您可能会发现这篇文章很有用:“参数列表太长”:超越参数和限制
附加参考:
ARG_MAX,新进程的最大参数长度
也许 ps 的 'w' 参数是你想要的。添加两个“w”以获得更大的输出。它告诉 ps 忽略终端的线宽。