首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Android httpConnection内存泄漏的socket-io

Android httpConnection内存泄漏的socket-io
EN

Stack Overflow用户
提问于 2016-04-30 20:54:49
回答 1查看 643关注 0票数 3

我在android上用socket-io。('com.github.nkzawa:socket.io-client:0.3.0')

在Nexus 10设备(Android4.2.1)上测试我的应用程序时,我发现在调用mSocket.connect()之后,libcore.net.http.HttpConnectionPool每12.7秒左右就创建一个libcore.net.http.HttpConnection对象。这会导致“太多打开的文件错误”,最终导致应用程序结冰或崩溃。

  • 不会发生在三星GS5设备上(Android4.4.2)
  • 如果我连接到非SSL服务器(http与https),则不会发生这种情况。
  • 我正在连接到一个自签名证书服务器--不确定它是否与泄漏有关。
  • 调用套接字断开不释放HttpConnection对象

在调查泄漏时,我创建了一个空的android项目来重现泄漏。下面我只附加了一个空的"hello“项目上面添加的代码。

  • 请注意,在我的原始应用程序-连接到服务器是成功的。onError回调被放置,但不被调用。在服务器端,只有一个连接是.Emitting,接收消息是成功的。只有当HttpConnection对象计数达到300左右时,才会出现“打开的文件太多”的错误,并导致各种问题。
  • 事实上,它只发生在某些android版本上,只发生在SSL连接上,而这种连接会导致泄漏,但断开连接并不能释放它,真的让我感到困惑。

-code

添加到build.gradle依赖项中

代码语言:javascript
复制
compile 'com.github.nkzawa:socket.io-client:0.3.0'

添加到Android声明中

代码语言:javascript
复制
<uses-permission android:name="android.permission.INTERNET" />

主要活动..。

代码语言:javascript
复制
import com.github.nkzawa.socketio.client.IO;
import com.github.nkzawa.socketio.client.Socket;

import java.net.URISyntaxException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;


public class MainActivity extends AppCompatActivity {



@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    .....

    mSocket.connect();
}

private TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
            return new java.security.cert.X509Certificate[] {};
        }

    public void checkClientTrusted(X509Certificate[] chain,String authType) throws CertificateException {
    }

    public void checkServerTrusted(X509Certificate[] chain,
                                   String authType) throws CertificateException {
    }
} };
private Socket mSocket;
{

        try
        {
            SSLContext sc = SSLContext.getInstance("TLS");
            sc.init(null, trustAllCerts, null);
            IO.setDefaultSSLContext(sc);
            HttpsURLConnection.setDefaultHostnameVerifier(new RelaxedHostNameVerifier());

            mSocket = IO.socket("https://10.0.0.1");
            mSocket.connect() ;

        }
        catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        }
        catch (URISyntaxException e) {
            e.printStackTrace();
        }

}

public static class RelaxedHostNameVerifier implements HostnameVerifier {
    public boolean verify(String hostname, SSLSession session) {
        return true;
    }
}
EN

回答 1

Stack Overflow用户

发布于 2016-05-03 18:19:55

好的。明白了。

  • 每12.7秒的连接泄漏就是ping。改变我服务器上的ping间隔有点帮助。但是事实证明,httpConnection在发送到服务器的每个Msg上都被泄露了。所以基本上这不是一个解决方案。

经过一番挖掘,我在网上找到了这个。http://android-developers.blogspot.co.il/2011/09/androids-http-clients.html

总结一下。

“在Froyo之前,HttpURLConnection有一些令人沮丧的bug。特别是,在可读的InputStream上调用close()可能会毒害连接池。为此,禁用连接池:”

代码语言:javascript
复制
private void disableConnectionReuseIfNecessary() {
    // HTTP connection reuse which was buggy pre-froyo
    if (Integer.parseInt(Build.VERSION.SDK) < Build.VERSION_CODES.FROYO) {
        System.setProperty("http.keepAlive", "false");
    }
}

如前所述,我正在遭受果冻豆的泄漏,而不是弗罗约。我移除了条件。

代码语言:javascript
复制
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    System.setProperty("http.keepAlive", "false") ;
    ...
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36960154

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档