2017-06-21 41 views
0

我试图扫描我的本地网络以查找带有特定打开的端口的设备。执行程序内存不足

当我做扫描6-7次我拿出内存不足。

WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(WIFI_SERVICE); 
    int ipAddress = wifiManager.getConnectionInfo().getIpAddress(); 
    @SuppressLint("DefaultLocale") String localIp = String.format("%d.%d.%d.%d", 
      (ipAddress & 0xff), 
      (ipAddress >> 8 & 0xff), 
      (ipAddress >> 16 & 0xff), 
      (ipAddress >> 24 & 0xff)); 

    String s = ServerUtilities.findServerIp(localIp); 

的findIpAdressFunction:

public static String findServerIp(String localIp) { 
    final String functionName = "findServerIp"; 
    final String[] serverIp = {""}; 
    long startTime = System.currentTimeMillis(); 
    String prefix = localIp.substring(0, localIp.lastIndexOf(".") + 1); 
    ConfigManager.printLog(functionName, "Started", AppConfig.LOG_TYPE_DEBUG); 

    if (localIp.length() > 0) { 
     for (int i = 0; i < 255; i++) { 
      final String testIp = prefix + String.valueOf(i); 
      Executors.newCachedThreadPool().execute(new Runnable() { 
       @Override 
       public void run() { 
        try { 
         InetAddress inetAddress = InetAddress.getByName(testIp); 
         checkInetAddress(inetAddress); 
        } catch (ConnectException e) { 
         if (e.toString().contains("ECONNREFUSED")) 
          ConfigManager.printLog(functionName, "Wrong server : connection refused", AppConfig.LOG_TYPE_VERBOSE); 
         else 
          ConfigManager.printLog(functionName, "Error : " + e.toString() + "\n\tip=" + testIp, AppConfig.LOG_TYPE_ERROR); 
        } catch (IOException e) { 
         ConfigManager.printLog(functionName, "Error scanning network : " + e.toString() + "\n\tip=" + testIp, AppConfig.LOG_TYPE_ERROR); 
        } 
       } 

       private void checkInetAddress(InetAddress inetAddress) throws IOException { 
        if (inetAddress.isReachable(500)) { 
         ConfigManager.printLog(functionName, "Testing " + testIp, AppConfig.LOG_TYPE_DEBUG); 
         new Socket(testIp, AppConfig.SERVER_PORT_CLIENT); 
         new Socket(testIp, AppConfig.SERVER_PORT_DOWNLOAD); 
         serverIp[0] = testIp; 
        } 
       } 
      }); 
     } 
    } else { 
     ConfigManager.printLog(functionName, "Error\n\tlocal IP is null or empty : " + localIp, AppConfig.LOG_TYPE_ERROR); 
    } 

    long endTime = System.currentTimeMillis(); 
    ConfigManager.printLog(functionName, 
      "Task finished\n\tresult : \"" + serverIp[0] + "\"\n\telapsed time : " + String.valueOf(endTime - startTime) + " (ms)" 
      , AppConfig.LOG_TYPE_INFO); 
    return serverIp[0]; 
} 

的logcat的错误:

E/AndroidRuntime: FATAL EXCEPTION: main 
                        Process: com.sanilea.speedclientserverside, PID: 23369 
                        java.lang.OutOfMemoryError: pthread_create (stack size 16384 bytes) failed: Try again 
                         at java.lang.VMThread.create(Native Method) 
                         at java.lang.Thread.start(Thread.java:1029) 
                         at java.util.concurrent.ThreadPoolExecutor.addWorker(ThreadPoolExecutor.java:920) 
                         at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1338) 
                         at com.sanilea.speedclientserverside.utility.ServerUtilities.findServerIp(ServerUtilities.java:163) 
                         at com.sanilea.speedclientserverside.activities.ConnexionActivity.scanAvailableNetwork(ConnexionActivity.java:96) 
                         at com.sanilea.speedclientserverside.activities.ConnexionActivity.access$000(ConnexionActivity.java:42) 
                         at com.sanilea.speedclientserverside.activities.ConnexionActivity$1.onClick(ConnexionActivity.java:64) 
                         at android.view.View.performClick(View.java:4508) 
                         at android.view.View$PerformClick.run(View.java:18675) 
                         at android.os.Handler.handleCallback(Handler.java:733) 
                         at android.os.Handler.dispatchMessage(Handler.java:95) 
                         at android.os.Looper.loop(Looper.java:136) 
                         at android.app.ActivityThread.main(ActivityThread.java:5590) 
                         at java.lang.reflect.Method.invokeNative(Native Method) 
                         at java.lang.reflect.Method.invoke(Method.java:515) 
                         at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1268) 
                         at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1084) 
                         at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:132) 
                         at dalvik.system.NativeStart.main(Native Method) 

误差与ExecutorService的包子,我不知道为什么...

感谢您的帮助。

回答

1

您正在为每个IP创建一个新的线程池。

您应该在for循环外面调用Executors.newCachedThreadPool()并将其结果存储在一个变量中。然后在循环内的该变量上调用Execute

+0

我也试过这样: ' ExecutorService executorService = Executors.newCachedThreadPool(); (int i = 0; i <255; i ++){ 如果(localIp.length()> 0){ final String testIp = prefix + String.valueOf(i); executorService.execute(new Runnable(){ ' – Flofloaud1034

+1

,并且还使用了一个固定大小的执行程序,或者你会掐掉设备 – eduyayo

+0

@eduyayo +1。我想'newCachedThreadPool'可能有一个硬限制,但是这个线程表示相反的https://stackoverflow.com/questions/949355/java-newcachedthreadpool-versus-newfixedthreadpool – chedabob

0

我只是添加:executorService.shutdownNow();并已解决