2017-06-21 18 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に新しいスレッドプールを作成しています。

Executors.newCachedThreadPool()をforループの外に呼び出し、その結果を変数に格納する必要があります。その後、ループ内のその変数にExecuteを呼び出します。

+0

私もこのようにしようとしました: ' ExecutorService executorService = Executors.newCachedThreadPool(); があれば(localIp.lengthは()> 0){ ため(INT i = 0; iが255 <; iは++){ 最終列testIp =接頭辞+ 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();それは解決されました