Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java堆空间异常和can';t删除从服务器接收的文件_Java - Fatal编程技术网

Java堆空间异常和can';t删除从服务器接收的文件

Java堆空间异常和can';t删除从服务器接收的文件,java,Java,我已经编写了下面的代码,但是在调用了将近150次之后,它抛出了“线程中的异常”thread-245“java.lang.OutOfMemoryError:java堆空间”问题就出现了(b=新字节[1024*1024];) Java代码: class Client implements Runnable { private Socket socket; private BufferedInputStream bufin = null; private BufferedOutputStream bu

我已经编写了下面的代码,但是在调用了将近150次之后,它抛出了“线程中的异常”thread-245“java.lang.OutOfMemoryError:java堆空间”问题就出现了(b=新字节[1024*1024];) Java代码:

class Client implements Runnable {
private Socket socket;
private BufferedInputStream bufin = null;
private BufferedOutputStream bufout = null;
String path;
private byte[] b;

Client(Socket socket, String path) {
    this.socket = socket;
    this.path = path;
}

@Override
public void run() {
    try {
        bufin = new BufferedInputStream(socket.getInputStream());
        bufout = new BufferedOutputStream(new FileOutputStream(path));

        b = new byte[1024 * 1024];
        int num = 0;
        while ((num = bufin.read(b)) != -1)
            bufout .write(b, 0, num);
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            bufin.close();
            bufout .close();
            b = null;
            socket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
}

我试图更清楚地描述这个问题。是这样的: 我写I ServerSocket,当客户端发送请求时,服务器将请求放入一个新线程,如下所示:

public void start() {
      boolean started = false;
      try {
              ServerSocket ss = new ServerSocket(8888);
              started = true;
              while (started) {
              String path = "C:/Pic/"+ new SimpleDateFormat("yy-MM-dd-HH_mm_ss_ms").format(new Date()) + ".jpg";
              Socket s = ss.accept();
              new Thread(new Client(s, path)).start();
             }
       } catch (IOException e) {
              e.printStackTrace();
       }
}

在这种情况下,服务器将接收来自任何客户端的请求。。。 还有第二个问题,我认为这个问题会导致Java堆空间异常,那就是当服务器收到图片时,在关闭服务器之前,图片不能从磁盘上删除,当我删除它时, 它说,“该操作无法完成,因为该文件是用Java(TM)平台SE二进制文件打开的”。而我已经在客户端线程中关闭了输入输出。 现在我无法找到问题的根源,1。为什么会发生堆异常anr2。服务器运行期间文件无法从磁盘删除的原因。
在您回复之前,非常感谢

内存不足,因为每个线程都在创建1MB数组缓冲区。您希望查看最大堆大小是多少(这取决于几个变量),并在命令行中增加最大大小,例如: java-Xmx1024M myclass.class

还有,你说你有150个客户。他们为什么不把垃圾收集起来?也许所有150个线程都会立即启动,所有线程都会同时抓取内存?我建议使用线程池来执行这些操作,这样就可以限制正在运行的客户端数量


因为服务器持有文件(您不能删除它)的问题是因为您得到了堆内存错误。当你得到这个的时候,所有的赌注都结束了。服务器仍保留对该文件的引用,而bufout.close()可能不起作用。

我怀疑堆耗尽不允许程序在异常occours之后,然后在finally块中正常运行,使流保持打开状态。我建议您在打开流之前更改程序以分配内存块;此外,要关闭finally块中的流,我建议您使用IOUtils commons io类,如示例中所述:


这允许您确保在finally块中关闭所有流。

您不需要b=null,因为它是在b超出范围时自动完成的。只需在本地声明b,在这里分配它并流。不需要声明全局范围内的所有内容。这很愚蠢,很难复习。打印异常时创建的/活动的/关闭的线程数。
byte[] data = "Hello, World".getBytes();

OutputStream out = null;
try {
 out = new FileOutputStream("foo.txt");
 out.write(data);
 out.close(); //close errors are handled
} catch (IOException e) {
 // error handling
} finally {
 IOUtils.closeQuietly(out);
}