CodenameOne icon indicating copy to clipboard operation
CodenameOne copied to clipboard

Memory leak on Sockets in iOS

Open shai-almog opened this issue 2 years ago • 1 comments

This leak is in the input/output stream of the native OS allocated here: https://github.com/codenameone/CodenameOne/blob/master/Ports/iOSPort/nativeSources/SocketImpl.m#L25

They are released on disconnect here so it seems this isn't invoked probably because this code isn't invoked due to isSocketConnected returning false.

I'm guessing that this is because socket doesn't have a finalizer that invokes dispose for us. That would explain the iOS specific behavior.

        terminalStatusThread.run(() -> 
        {
            try
            {
                InetAddress localAddress = InetAddress.getLocalHost();
                String      ip           = localAddress.getHostAddress();
                String      segment      = ip.substring(0, ip.lastIndexOf(".") + 1);

                for(int i=1;i<255;i++)
                {
                    String current = segment + i;

                    if (!ip.equals(current) && !excludeIps.contains(ip))
                    {
                        Socket socket = new Socket(10);

                        synchronized(socket)
                        {
                            com.codename1.io.Socket.connect(current, DEFAULT_REST_API_PORT, socket);
                            socket.wait();
                        }

                        if (socket.isConnected())
                        {
                            socket.close();
                        }
                    }
                }
            }
            catch (Exception e)
            {
                //Log.e(e);
            }
        });


    class Socket extends SocketConnection {
        private InputStream is;
        
        public Socket(int connectTimeout)
        {
            super(connectTimeout);
        }
        
        @Override
        public synchronized void connectionError(int errorCode, String message)
        {
            notify();
        }

        @Override
        public synchronized void connectionEstablished(InputStream is, OutputStream os)
        {
            this.is = is;
            notify();
        }
        
        public synchronized void close()
        {
            if (isConnected())
            {
                try
                {
                    is.close();
                }
                catch(IOException e)
                {
                    com.codename1.io.Log.e(e);
                }
            }
        }
    }

shai-almog avatar Aug 19 '23 06:08 shai-almog

Let me know when this makes it to the public builds and I’ll retest.

I’m still concerned that this bug apparently killed the gc with no immediate effect, leaving a crippled app to die at some later time.

ddyer0 avatar Oct 28 '23 19:10 ddyer0