如何增加 /proc/pid/cmdline 4096 字节限制?
对于类路径很长的 Java 应用程序,使用 ps 时我看不到在 arg 列表末尾附近指定的主类。 我认为这源于我的 Ubuntu 系统对 /proc/pid/cmdline 的大小限制。 我怎样才能增加这个限制?
For my Java apps with very long classpaths, I cannot see the main class specified near the end of the arg list when using ps. I think this stems from my Ubuntu system's size limit on /proc/pid/cmdline. How can I increase this limit?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
对于查看 Java 进程 jps 非常有用。
这将为您提供主类和 jvm 参数:
For looking at Java processes jps is very useful.
This will give you the main class and jvm args:
您无法动态更改此设置,该限制在内核中硬编码为 fs/proc/base.c 中的 PAGE_SIZE:
You can't change this dynamically, the limit is hard-coded in the kernel to PAGE_SIZE in fs/proc/base.c:
我暂时解决了 ps (或者更确切地说 /proc/PID/cmdline )的 4096 个字符命令行参数限制,方法是使用一个小脚本来替换 java 命令。
在开发过程中,我总是使用来自 SUN 的未打包的 JDK 版本,并且无论是 Linux 还是 Windows,从不使用操作系统已安装的 JRE 或 JDK(例如,下载 bin 与 rpm.bin)。
我不建议更改默认 Java 安装的脚本(例如,因为它可能会破坏更新或被覆盖或产生问题或......)
因此假设 java 命令位于 /x/jdks/jdk1.6.0_16_x32/bin/java 中
首先将实际的二进制文件移走:
然后创建一个脚本 /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 shell 脚本。
我认为 shell 对命令行参数的数量也有一些限制,记不清了,但可能是 64K 字符。
您可以更改脚本以从 /tmp/java.PROCESS_ID.cmdline 中删除命令行文本
最后,
在获得命令行后,我总是将脚本移动到“java.script”之类的位置,并将实际的二进制 java.orig 复制(cp -a)回 java。 我仅在达到 4K 限制时才使用该脚本。
转义字符可能存在问题,甚至可能存在路径中的空格等问题,但它对我来说效果很好。
I temporarily get around the 4096 character command line argument limitation of ps (or rather /proc/PID/cmdline) is by using a small script to replace the java command.
During development, I always use an unpacked JDK version from SUN and never use the installed JRE or JDK of the OS no matter if Linux or Windows (eg. download the bin versus the rpm.bin).
I do not recommend changing the script for your default Java installation (e.g. because it might break updates or get overwritten or create problems or ...)
So assuming the java command is in /x/jdks/jdk1.6.0_16_x32/bin/java
first move the actual binary away:
then create a script /x/jdks/jdk1.6.0_16_x32/bin/java like e.g.:
and then make the script runnable
in case of copy and pasting the above, you should make sure that there are not extra spaces in /x/jdks/jdk1.6.0_16_x32/bin/java and #!/bin/bash is the first line
The complete command line ends up in e.g. /tmp/java.26835.cmdline where 26835 is the PID of the shell script.
I think there is also some shell limit on the number of command line arguments, cannot remember but it was possibly 64K characters.
you can change the script to remove the command line text from /tmp/java.PROCESS_ID.cmdline
at the end
After I got the commandline, I always move the script to something like "java.script" and copy (cp -a) the actual binary java.orig back to java. I only use the script when I hit the 4K limit.
There might be problems with escaped characters and maybe even spaces in paths or such, but it works fine for me.
您可以使用
jconsole
来访问原始命令行,而不受所有长度限制。You can use
jconsole
to get access to the original command line without all the length limits.可以使用较新的 Linux 发行版,其中此限制已被删除,例如 RHEL 6.8 或更高版本
“ps 命令的 /proc/pid/cmdline 文件长度限制之前在内核中硬编码为 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
It is possible to use newer linux distributions, where this limit was removed, for example RHEL 6.8 or later
"The /proc/pid/cmdline file length limit for the ps command was previously hard-coded in the kernel to 4096 characters. This update makes sure the length of /proc/pid/cmdline is unlimited, which is especially useful for listing processes with long command line arguments. (BZ#1100069)"
https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/6/html/6.8_Release_Notes/new_features_kernel.html
对于基于 Java 的程序,您只想检查主类获得的命令行参数,您可以运行:
For Java based programs where you are just interested in inspecting the command line args your main class got, you can run:
我非常确定,如果您实际上看到 /proc/$pid/cmdline 中的参数被截断,那么您实际上超出了操作系统支持的最大参数长度。 据我所知,在 Linux 中,大小仅限于内存页面大小。 请参阅“ps ww”长度限制
解决这个问题的唯一方法是重新编译内核。 如果您有兴趣解决这个问题,那么您可能会发现这篇文章很有用:"参数列表long":超越参数和限制
其他参考:
ARG_MAX,新进程的参数最大长度
I'm pretty sure that if you're actually seeing the arguments truncated in /proc/$pid/cmdline then you're actually exceeding the maximum argument length supported by the OS. As far as I can tell, in Linux, the size is limited to the memory page size. See "ps ww" length restriction for reference.
The only way to get around that would be to recompile the kernel. If you're interested in going that far to resolve this then you may find this post useful: "Argument list too long": Beyond Arguments and Limitations
Additional reference:
ARG_MAX, maximum length of arguments for a new process
也许 ps 的“w”参数就是您想要的。 添加两个“w”以获得更大的输出。 它告诉 ps 忽略终端的线宽。
Perhaps the 'w' parameter to ps is what you want. Add two 'w' for greater output. It tells ps to ignore the line width of the terminal.