在CentOS 6.4的/opt/wso2保存新文件时,我的Java应用程序返回下面的exception:
Caused by java.io.FileNotFoundException: ... (No space left on device)
Caused by: java.io.FileNotFoundException: /opt/wso2/FrameworkFiles/trk_2014062500042488825_TRCK_PatfallHospis_pFromHospis_66601fb3-a03c-4149-93c3-6892e0a10fea.txt (No space left on device) at java.io.FileOutputStream.open(Native Method) at java.io.FileOutputStream.<init>(FileOutputStream.java:212) at java.io.FileOutputStream.<init>(FileOutputStream.java:99) at com.avintis.esb.framework.adapter.wso2.FrameworkAdapterWSO2.sendMessages(FrameworkAdapterWSO2.java:634) ... 23 more
但是当我运行df -a我可以看到分区仍然有足够的可用空间:
[root@stzsi466 wso2]# df -a Filesystem 1K-blocks Used Available Use% Mounted on /dev/mapper/vg_stzsi466-lv_root 12054824 2116092 9326380 19% / proc 0 0 0 - /proc sysfs 0 0 0 - /sys devpts 0 0 0 - /dev/pts tmpfs 4030764 0 4030764 0% /dev/shm /dev/sda1 495844 53858 416386 12% /boot /dev/sdb1 51605436 1424288 47559744 3% /opt/wso2 none 0 0 0 - /proc/sys/fs/binfmt_misc [root@stzsi466 ~]# df -i Filesystem Inodes IUsed IFree IUse% Mounted on /dev/mapper/vg_stzsi466-lv_root 765536 45181 720355 6% / tmpfs 1007691 1 1007690 1% /dev/shm /dev/sda1 128016 44 127972 1% /boot /dev/sdb1 3276800 6137 3270663 1% /opt/wso2
这里有什么问题? 它是由CentOS 6.4上的Java引起的吗? 我有另一台服务器运行RedHat的REHL 6.4和一切正常 – 相同的Java等
有谁知道这个问题?
所以从堆栈跟踪中,我们可以看到当创buildFileOutputStream对象时,在该代码内部调用open()会失败,然后抛出一个FileNotFoundException,并显示“No space left on device”错误消息。
查看失败的代码(FileOutputStream.java)是很有趣的:
public FileOutputStream(File file, boolean append) throws FileNotFoundException { String name = (file != null ? file.getPath() : null); SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkWrite(name); } if (name == null) { throw new NullPointerException(); } this.fd = new FileDescriptor(); this.append = append; fd.incrementAndGetUseCount(); open(name, append); /* HERE */ }
所以这是对本地代码(FileOutputStream_md.c)的调用:
Java_java_io_FileOutputStream_open(JNIEnv *env, jobject this, jstring path, jboolean append) { fileOpen(env, this, path, fos_fd, O_WRONLY | O_CREAT | (append ? O_APPEND : O_TRUNC)); }
和fileOpen(io_util_md.c):
fileOpen(JNIEnv *env, jobject this, jstring path, jfieldID fid, int flags) { WITH_PLATFORM_STRING(env, path, ps) { FD fd; #ifdef __linux__ /* Remove trailing slashes, since the kernel won't */ char *p = (char *)ps + strlen(ps) - 1; while ((p > ps) && (*p == '/')) *p-- = '\0'; #endif fd = JVM_Open(ps, flags, 0666); /* HERE IS WHERE THINGS BREAK */ if (fd >= 0) { SET_FD(this, fd, fid); } else { throwFileNotFoundException(env, path); /* EXCEPTION */ } } END_PLATFORM_STRING(env, ps); }
和JVM_Open(jvm.cpp):
JVM_LEAF(jint, JVM_Open(const char *fname, jint flags, jint mode)) JVMWrapper2("JVM_Open (%s)", fname); //%note jvm_r6 int result = os::open(fname, flags, mode); if (result >= 0) { return result; } else { switch(errno) { case EEXIST: return JVM_EEXIST; /* returns -100, will trigger Exception */ default: return -1; /* returns -1, will trigger Exception */ } } JVM_END
和os :: open只是fdopen(2)系统调用的一个包装。
你能随时重现这个错误吗? 如果是这样,请使用strace -e trace=fopen,fdopen,freopen和post结果(或者使用strace -p <PID>附加到正在运行的进程)运行命令。