Android-OutOfMemoryError:无法分配JNI Env

问题描述 投票:0回答:1

我正在使用Java套接字在带有this的wifi p2p网络中的android设备之间发送/接收字节。每次设备连接/断开连接时,我都会循环一个线程(如果有组所有者)。

        public void onConnectionInfoAvailable(WifiP2pInfo info) {
            if(info.isGroupOwner) {
                for (int a = 8001; a < 8255; a += 1) {
                    Server server = new Server(a);
                    server.start();
                    serverHashMap.put(a, server);
                }
            }
        }

如果只有1台设备连接到“组所有者”,并且该设备断开连接,然后再次重新连接,则没有错误。如果2个设备已连接到组所有者,然后另一个断开连接,然后再次重新连接,则我收到OutOfMemoryError无法分配JNI Env

2019-11-07 09:15:04.477 5882-5882/com.example.example103 E/art: ashmem_create_region failed for 'indirect ref table': Too many open files
2019-11-07 09:15:04.477 5882-5882/com.example.example103 W/art: Throwing OutOfMemoryError "Could not allocate JNI Env"
2019-11-07 09:15:04.478 5882-5882/com.example.example103 D/AndroidRuntime: Shutting down VM
2019-11-07 09:15:04.479 5882-5882/com.example.example103 E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.example103, PID: 5882
    java.lang.OutOfMemoryError: Could not allocate JNI Env
        at java.lang.Thread.nativeCreate(Native Method)
        at java.lang.Thread.start(Thread.java:745)
        at com.example.example103.MainActivity$2.onConnectionInfoAvailable(MainActivity.java:100)
        at android.net.wifi.p2p.WifiP2pManager$Channel$P2pHandler.handleMessage(WifiP2pManager.java:787)
        at android.os.Handler.dispatchMessage(Handler.java:105)
        at android.os.Looper.loop(Looper.java:156)
        at android.app.ActivityThread.main(ActivityThread.java:6623)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:942)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:832)

这是服务器线程和消息线程的代码


    public class Server extends Thread {
        Socket serverSocket;
        ServerSocket trueServerSocket;
        int serverPort;

        public Server(int port) {
            try {
                serverPort = port;
                trueServerSocket = new ServerSocket();
                trueServerSocket.setReuseAddress(true);
                trueServerSocket.bind(new InetSocketAddress(serverPort));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        @Override
        public void run() {
            try {
                serverSocket = trueServerSocket.accept();
                serverSocket.setReuseAddress(true);
                Message message = new Message(serverSocket);
                message.start();
                messageHashMap.put(serverPort, message);
                trueServerSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    public class Message extends Thread {
        private Socket socket;
        private InputStream inputStream;
        private OutputStream outputStream;

        public Message(Socket skt) {
            try {
                socket = skt;
                inputStream = socket.getInputStream();
                outputStream = socket.getOutputStream();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        public void write(byte[] bytes) {
            try {
                outputStream.write(bytes);
                outputStream.flush();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void run() {
            byte[] buffer = new byte[1024];
            int bytes;

            while (socket != null) {
                try {
                    bytes = inputStream.read(buffer);
                    if (bytes > 0) {
                        handler.obtainMessage(1, bytes, -1, buffer).sendToTarget();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

我真的可以使用帮助。谢谢。

java android sockets out-of-memory
1个回答
0
投票

我刚刚解决了。我认为 ?我添加了一个ExecutorService并将线程放在那里,以便每当有任何客户端连接/断开连接时,我都将使用newCachedThreadPool()方法初始化ExecutorService。现在,onConnectionInfoAvailable()中的代码将如下所示。

                executorService = Executors.newCachedThreadPool();
                for (int a = 8001; a < 8255; a += 1) {
                    Server server = new Server(a);
                    executorService.submit(server);
                }

我刚刚对其进行了测试,并且可以正常工作。如果您有任何建议,澄清,请发表评论。

© www.soinside.com 2019 - 2024. All rights reserved.