日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
Process 創(chuàng)建+控制+分析 經(jīng)驗(yàn)淺談

無論是Android亦或者Java中或多或少需要調(diào)用底層的一些命令,執(zhí)行一些參數(shù);

在石拐等地區(qū),都構(gòu)建了全面的區(qū)域性戰(zhàn)略布局,加強(qiáng)發(fā)展的系統(tǒng)性、市場前瞻性、產(chǎn)品創(chuàng)新能力,以專注、極致的服務(wù)理念,為客戶提供做網(wǎng)站、成都做網(wǎng)站 網(wǎng)站設(shè)計(jì)制作定制網(wǎng)站,公司網(wǎng)站建設(shè),企業(yè)網(wǎng)站建設(shè),品牌網(wǎng)站設(shè)計(jì),成都全網(wǎng)營銷推廣,外貿(mào)營銷網(wǎng)站建設(shè),石拐網(wǎng)站建設(shè)費(fèi)用合理。

此時(shí)我們需要用到Java的process來創(chuàng)建一個(gè)子進(jìn)程,之所以是子進(jìn)程是因?yàn)榇诉M(jìn)程依賴于發(fā)起創(chuàng)建請求的進(jìn)程,如果發(fā)起者被Kill那個(gè)子進(jìn)程也將Kill。

對于Process相信使用過的朋友一定不會陌生,它具有如下特點(diǎn):

1.創(chuàng)建簡單

2.控制難

3.容易導(dǎo)致無法創(chuàng)建子進(jìn)程

4.如果是多線程那么很有可能造成內(nèi)存溢出

以上現(xiàn)象如果你只是偶爾使用一次,創(chuàng)建一個(gè)進(jìn)程或許你什么都沒有感覺到,但是如果你使用了多線程,進(jìn)行了大量的創(chuàng)建,以上問題你都會遇到。

相關(guān):http://blog.csdn.net/qiujuer/article/details/38142273,http://blog.csdn.net/qiujuer/article/details/38086071

這兩個(gè)星期一直在研究上面的問題,我要做的軟件是在Android中進(jìn)行TraceRoute,由于手機(jī)不可能完全Root所以不能采用JNI來發(fā)送ICMP請求的方式,最終只能使用創(chuàng)建進(jìn)程方式進(jìn)行;具體實(shí)現(xiàn)思路是:使用PING命令來PING百度等地址,在PING命令中加入TTL,得到每一次的IP地址,當(dāng)IP地址與目標(biāo)IP地址符合時(shí)退出,并且還需要單獨(dú)PING一次每一跳的延遲和丟包。

單線程:PING 百度 TTL=1 =》 得到IP,PING IP 得到延遲丟包,改變TTL,進(jìn)行下一次PING,直到所得到的IP與目標(biāo)(百度)一樣時(shí)停止。按照上面的思路一次需要創(chuàng)建兩個(gè)子進(jìn)程,一般到百度時(shí)TTL大約為12跳左右,所以就是2*12=24個(gè)子進(jìn)程;如果是在單線程下簡單明了,但是速度慢,整個(gè)過程大約需要1分鐘左右。

多線程:同時(shí)發(fā)起3個(gè)線程進(jìn)行3跳測試TTL=(1,2,3),測試完成后測試下一批數(shù)據(jù)TTL=(4,5,6),如果也是12跳的話,那么也是24個(gè)子進(jìn)程,但是整體耗時(shí)將會為1/3.可見此時(shí)效率較高。

但是多線程需要考慮的是線程的同步問題,以及得到數(shù)據(jù)后的寫入問題,這些贊不談,只談進(jìn)程問題。經(jīng)過我的測試假如現(xiàn)在測試100個(gè)網(wǎng)站的TraceRoute數(shù)據(jù),在上層控制一次測試4個(gè)網(wǎng)站,底層實(shí)現(xiàn)并發(fā)3個(gè)線程,此時(shí)在一定時(shí)間內(nèi)將會同時(shí)存在3*4個(gè)進(jìn)程。按照平均每個(gè)網(wǎng)站12跳來算:12*2*100=240個(gè)子進(jìn)程,需要的子線程為12*100=120個(gè)。

這個(gè)時(shí)候問題來了,假如現(xiàn)在程序子進(jìn)程不正常了,遇到了一個(gè)一定的問題導(dǎo)致進(jìn)程無法執(zhí)行完成,此時(shí)你的現(xiàn)象是:一個(gè)子進(jìn)程卡住,隨后創(chuàng)建的所有子進(jìn)程都卡住。假如最上層線程做了任務(wù)時(shí)間限制,那么到時(shí)間后將會嘗試銷毀,但是你會發(fā)現(xiàn)無法銷毀,所持有的線程也不會銷毀。但是上層以為銷毀掉了,然后繼續(xù)進(jìn)行下一批的數(shù)據(jù)測試,此時(shí)你的線程數(shù)量會逐漸增加,如果100任務(wù)下來你的線程或許會達(dá)到3*4*100=1200如果有前期沒有這樣的情況那個(gè)就是一半:600個(gè)線程左右,如果后期還有任務(wù)將會繼續(xù)增加但是卻永遠(yuǎn)不會銷毀,但是我們知道JVM的內(nèi)存是有限的,所以此時(shí)將會出現(xiàn)內(nèi)存溢出。
以上就是我遇到的問題,我***改為了等待線程完全返回后再進(jìn)行下一批數(shù)據(jù)測試,此時(shí)內(nèi)存溢出是解決了,但是任務(wù)卻一直卡住在哪里了,永遠(yuǎn)也不走。我就在想要解決這一的問題需要解決根本上的問題才行,經(jīng)過研究我發(fā)現(xiàn)在程序創(chuàng)建了子進(jìn)程后JVM將會創(chuàng)建一個(gè)子進(jìn)程管理線程:“ProcessManager”:

正常情況下該線程狀態(tài)為Native,但是如果創(chuàng)建大量子進(jìn)程后有可能會出現(xiàn)此線程為Monitor狀態(tài),過一段時(shí)間后所有創(chuàng)建子進(jìn)程的線程狀態(tài)也將會變?yōu)镸onitor狀態(tài),然后將一直死鎖,后面創(chuàng)建線程也是繼續(xù)死鎖,無法繼續(xù)。

通過查看ProcessManager源碼發(fā)現(xiàn),其中啟動了一個(gè)線程用于監(jiān)聽子進(jìn)程狀態(tài),同時(shí)管理子進(jìn)程,比如輸出消息以及關(guān)閉子進(jìn)程等操作,具體如下

 
 
 
 
  1. /** 
  2.  * Copyright (C) 2007 The Android Open Source Project 
  3.  * 
  4.  * Licensed under the Apache License, Version 2.0 (the "License"); 
  5.  * you may not use this file except in compliance with the License. 
  6.  * You may obtain a copy of the License at 
  7.  * 
  8.  *      http://www.apache.org/licenses/LICENSE-2.0 
  9.  * 
  10.  * Unless required by applicable law or agreed to in writing, software 
  11.  * distributed under the License is distributed on an "AS IS" BASIS, 
  12.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
  13.  * See the License for the specific language governing permissions and 
  14.  * limitations under the License. 
  15.  */ 
  16.   
  17. package java.lang; 
  18.   
  19. import java.io.File; 
  20. import java.io.FileDescriptor; 
  21. import java.io.FileInputStream; 
  22. import java.io.FileOutputStream; 
  23. import java.io.IOException; 
  24. import java.io.InputStream; 
  25. import java.io.OutputStream; 
  26. import java.lang.ref.ReferenceQueue; 
  27. import java.lang.ref.WeakReference; 
  28. import java.util.HashMap; 
  29. import java.util.Map; 
  30. import java.util.Arrays; 
  31. import java.util.logging.Logger; 
  32. import java.util.logging.Level; 
  33.   
  34. /*** 
  35.  * Manages child processes. 
  36.  * 
  37.  * 

    Harmony's native implementation (for comparison purposes): 

  38.  * http://tinyurl.com/3ytwuq 
  39.  */ 
  40. final class ProcessManager { 
  41.   
  42.     /*** 
  43.      * constant communicated from native code indicating that a 
  44.      * child died, but it was unable to determine the status 
  45.      */ 
  46.     private static final int WAIT_STATUS_UNKNOWN = -1; 
  47.   
  48.     /*** 
  49.      * constant communicated from native code indicating that there 
  50.      * are currently no children to wait for 
  51.      */ 
  52.     private static final int WAIT_STATUS_NO_CHILDREN = -2; 
  53.   
  54.     /*** 
  55.      * constant communicated from native code indicating that a wait() 
  56.      * call returned -1 and set an undocumented (and hence unexpected) errno 
  57.      */ 
  58.     private static final int WAIT_STATUS_STRANGE_ERRNO = -3; 
  59.   
  60.     /*** 
  61.      * Initializes native static state. 
  62.      */ 
  63.     static native void staticInitialize(); 
  64.     static { 
  65.         staticInitialize(); 
  66.     } 
  67.   
  68.     /*** 
  69.      * Map from pid to Process. We keep weak references to the Process objects 
  70.      * and clean up the entries when no more external references are left. The 
  71.      * process objects themselves don't require much memory, but file 
  72.      * descriptors (associated with stdin/out/err in this case) can be 
  73.      * a scarce resource. 
  74.      */ 
  75.     private final Map processReferences 
  76.             = new HashMap(); 
  77.   
  78.     /*** Keeps track of garbage-collected Processes. */ 
  79.     private final ProcessReferenceQueue referenceQueue 
  80.             = new ProcessReferenceQueue(); 
  81.   
  82.     private ProcessManager() { 
  83.         // Spawn a thread to listen for signals from child processes. 
  84.         Thread processThread = new Thread(ProcessManager.class.getName()) { 
  85.             @Override 
  86.             public void run() { 
  87.                 watchChildren(); 
  88.             } 
  89.         }; 
  90.         processThread.setDaemon(true); 
  91.         processThread.start(); 
  92.     } 
  93.   
  94.     /*** 
  95.      * Kills the process with the given ID. 
  96.      * 
  97.      * @parm pid ID of process to kill 
  98.      */ 
  99.     private static native void kill(int pid) throws IOException; 
  100.   
  101.     /*** 
  102.      * Cleans up after garbage collected processes. Requires the lock on the 
  103.      * map. 
  104.      */ 
  105.     void cleanUp() { 
  106.         ProcessReference reference; 
  107.         while ((reference = referenceQueue.poll()) != null) { 
  108.             synchronized (processReferences) { 
  109.                 processReferences.remove(reference.processId); 
  110.             } 
  111.         } 
  112.     } 
  113.   
  114.     /*** 
  115.      * Listens for signals from processes and calls back to 
  116.      * {@link #onExit(int,int)}. 
  117.      */ 
  118.     native void watchChildren(); 
  119.   
  120.     /*** 
  121.      * Called by {@link #watchChildren()} when a child process exits. 
  122.      * 
  123.      * @param pid ID of process that exited 
  124.      * @param exitValue value the process returned upon exit 
  125.      */ 
  126.     void onExit(int pid, int exitValue) { 
  127.         ProcessReference processReference = null; 
  128.   
  129.         synchronized (processReferences) { 
  130.             cleanUp(); 
  131.             if (pid >= 0) { 
  132.                 processReference = processReferences.remove(pid); 
  133.             } else if (exitValue == WAIT_STATUS_NO_CHILDREN) { 
  134.                 if (processReferences.isEmpty()) { 
  135.                     /** 
  136.                      * There are no eligible children; wait for one to be 
  137.                      * added. The wait() will return due to the 
  138.                      * notifyAll() call below. 
  139.                      */ 
  140.                     try { 
  141.                         processReferences.wait(); 
  142.                     } catch (InterruptedException ex) { 
  143.                         // This should never happen. 
  144.                         throw new AssertionError("unexpected interrupt"); 
  145.                     } 
  146.                 } else { 
  147.                     /** 
  148.                      * A new child was spawned just before we entered 
  149.                      * the synchronized block. We can just fall through 
  150.                      * without doing anything special and land back in 
  151.                      * the native wait(). 
  152.                      */ 
  153.                 } 
  154.             } else { 
  155.                 // Something weird is happening; abort! 
  156.                 throw new AssertionError("unexpected wait() behavior"); 
  157.             } 
  158.         } 
  159.   
  160.         if (processReference != null) { 
  161.             ProcessImpl process = processReference.get(); 
  162.             if (process != null) { 
  163.                 process.setExitValue(exitValue); 
  164.             } 
  165.         } 
  166.     } 
  167.   
  168.     /*** 
  169.      * Executes a native process. Fills in in, out, and err and returns the 
  170.      * new process ID upon success. 
  171.      */ 
  172.     static native int exec(String[] command, String[] environment, 
  173.             String workingDirectory, FileDescriptor in, FileDescriptor out, 
  174.             FileDescriptor err, boolean redirectErrorStream) throws IOException; 
  175.   
  176.     /*** 
  177.      * Executes a process and returns an object representing it. 
  178.      */ 
  179.     Process exec(String[] taintedCommand, String[] taintedEnvironment, File workingDirectory, 
  180.             boolean redirectErrorStream) throws IOException { 
  181.         // Make sure we throw the same exceptions as the RI. 
  182.         if (taintedCommand == null) { 
  183.             throw new NullPointerException(); 
  184.         } 
  185.         if (taintedCommand.length == 0) { 
  186.             throw new IndexOutOfBoundsException(); 
  187.         } 
  188.   
  189.         // Handle security and safety by copying mutable inputs and checking them. 
  190.         String[] command = taintedCommand.clone(); 
  191.         String[] environment = taintedEnvironment != null ? taintedEnvironment.clone() : null; 
  192.         SecurityManager securityManager = System.getSecurityManager(); 
  193.         if (securityManager != null) { 
  194.             securityManager.checkExec(command[0]); 
  195.         } 
  196.         // Check we're not passing null Strings to the native exec. 
  197.         for (String arg : command) { 
  198.             if (arg == null) { 
  199.                 throw new NullPointerException(); 
  200.             } 
  201.         } 
  202.         // The environment is allowed to be null or empty, but no element may be null. 
  203.         if (environment != null) { 
  204.             for (String env : environment) { 
  205.                 if (env == null) { 
  206.                     throw new NullPointerException(); 
  207.                 } 
  208.             } 
  209.         } 
  210.   
  211.         FileDescriptor in = new FileDescriptor(); 
  212.         FileDescriptor out = new FileDescriptor(); 
  213.         FileDescriptor err = new FileDescriptor(); 
  214.   
  215.         String workingPath = (workingDirectory == null) 
  216.                 ? null 
  217.                 : workingDirectory.getPath(); 
  218.   
  219.         // Ensure onExit() doesn't access the process map before we add our 
  220.         // entry. 
  221.         synchronized (processReferences) { 
  222.             int pid; 
  223.             try { 
  224.                 pid = exec(command, environment, workingPath, in, out, err, redirectErrorStream); 
  225.             } catch (IOException e) { 
  226.                 IOException wrapper = new IOException("Error running exec()." 
  227.                         + " Command: " + Arrays.toString(command) 
  228.                         + " Working Directory: " + workingDirectory 
  229.                         + " Environment: " + Arrays.toString(environment)); 
  230.                 wrapper.initCause(e); 
  231.                 throw wrapper; 
  232.             } 
  233.             ProcessImpl process = new ProcessImpl(pid, in, out, err); 
  234.             ProcessReference processReference 
  235.                     = new ProcessReference(process, referenceQueue); 
  236.             processReferences.put(pid, processReference); 
  237.   
  238.             /** 
  239.              * This will wake up the child monitor thread in case there 
  240.              * weren't previously any children to wait on. 
  241.              */ 
  242.             processReferences.notifyAll(); 
  243.   
  244.             return process; 
  245.         } 
  246.     } 
  247.   
  248.     static class ProcessImpl extends Process { 
  249.   
  250.         /*** Process ID. */ 
  251.         final int id; 
  252.   
  253.         final InputStream errorStream; 
  254.   
  255.         /*** Reads output from process. */ 
  256.         final InputStream inputStream; 
  257.   
  258.         /*** Sends output to process. */ 
  259.         final OutputStream outputStream; 
  260.   
  261.         /*** The process's exit value. */ 
  262.         Integer exitValue = null; 
  263.         final Object exitValueMutex = new Object(); 
  264.   
  265.         ProcessImpl(int id, FileDescriptor in, FileDescriptor out, 
  266.                 FileDescriptor err) { 
  267.             this.id = id; 
  268.   
  269.             this.errorStream = new ProcessInputStream(err); 
  270.             this.inputStream = new ProcessInputStream(in); 
  271.             this.outputStream = new ProcessOutputStream(out); 
  272.         } 
  273.   
  274.         public void destroy() { 
  275.             try { 
  276.                 kill(this.id); 
  277.             } catch (IOException e) { 
  278.                 Logger.getLogger(Runtime.class.getName()).log(Level.FINE, 
  279.                         "Failed to destroy process " + id + ".", e); 
  280.             } 
  281.         } 
  282.   
  283.         public int exitValue() { 
  284.             synchronized (exitValueMutex) { 
  285.                 if (exitValue == null) { 
  286.                     throw new IllegalThreadStateException( 
  287.                             "Process has not yet terminated."); 
  288.                 } 
  289.   
  290.                 return exitValue; 
  291.             } 
  292.         } 
  293.   
  294.         public InputStream getErrorStream() { 
  295.             return this.errorStream; 
  296.         } 
  297.   
  298.         public InputStream getInputStream() { 
  299.             return this.inputStream; 
  300.         } 
  301.   
  302.         public OutputStream getOutputStream() { 
  303.             return this.outputStream; 
  304.         } 
  305.   
  306.         public int waitFor() throws InterruptedException { 
  307.             synchronized (exitValueMutex) { 
  308.                 while (exitValue == null) { 
  309.                     exitValueMutex.wait(); 
  310.                 } 
  311.                 return exitValue; 
  312.             } 
  313.         } 
  314.   
  315.         void setExitValue(int exitValue) { 
  316.             synchronized (exitValueMutex) { 
  317.                 this.exitValue = exitValue; 
  318.                 exitValueMutex.notifyAll(); 
  319.             } 
  320.         } 
  321.   
  322.         @Override 
  323.         public String toString() { 
  324.             return "Process[id=" + id + "]";  
  325.         } 
  326.     } 
  327.   
  328.     static class ProcessReference extends WeakReference { 
  329.   
  330.         final int processId; 
  331.   
  332.         public ProcessReference(ProcessImpl referent, 
  333.                 ProcessReferenceQueue referenceQueue) { 
  334.             super(referent, referenceQueue); 
  335.             this.processId = referent.id; 
  336.         } 
  337.     } 
  338.   
  339.     static class ProcessReferenceQueue extends ReferenceQueue { 
  340.   
  341.         @Override 
  342.         public ProcessReference poll() { 
  343.             // Why couldn't they get the generics right on ReferenceQueue? :( 
  344.             Object reference = super.poll(); 
  345.             return (ProcessReference) reference; 
  346.         } 
  347.     } 
  348.   
  349.     static final ProcessManager instance = new ProcessManager(); 
  350.   
  351.     /*** Gets the process manager. */ 
  352.     static ProcessManager getInstance() { 
  353.         return instance; 
  354.     } 
  355.   
  356.     /*** Automatically closes fd when collected. */ 
  357.     private static class ProcessInputStream extends FileInputStream { 
  358.   
  359.         private FileDescriptor fd; 
  360.   
  361.         private ProcessInputStream(FileDescriptor fd) { 
  362.             super(fd); 
  363.             this.fd = fd; 
  364.         } 
  365.   
  366.         @Override 
  367.         public void close() throws IOException { 
  368.             try { 
  369.                 super.close(); 
  370.             } finally { 
  371.                 synchronized (this) { 
  372.                     if (fd != null && fd.valid()) { 
  373.                         try { 
  374.                             ProcessManager.close(fd); 
  375.                         } finally { 
  376.                             fd = null; 
  377.                         } 
  378.                     } 
  379.                 } 
  380.             } 
  381.         } 
  382.     } 
  383.   
  384.     /*** Automatically closes fd when collected. */ 
  385.     private static class ProcessOutputStream extends FileOutputStream { 
  386.   
  387.         private FileDescriptor fd; 
  388.   
  389.         private ProcessOutputStream(FileDescriptor fd) { 
  390.             super(fd); 
  391.             this.fd = fd; 
  392.         } 
  393.   
  394.         @Override 
  395.         public void close() throws IOException { 
  396.             try { 
  397.                 super.close(); 
  398.             } finally { 
  399.                 synchronized (this) { 
  400.                     if (fd != null && fd.valid()) { 
  401.                         try { 
  402.                             ProcessManager.close(fd); 
  403.                         } finally { 
  404.                             fd = null; 
  405.                         } 
  406.                     } 
  407.                 } 
  408.             } 
  409.         } 
  410.     } 
  411.   
  412.     /*** Closes the given file descriptor. */ 
  413.     private static native void close(FileDescriptor fd) throws IOException; 

#p#

在其中有一個(gè)“ native void watchChildren();”方法,此方法為線程主方法,具體實(shí)現(xiàn)可以看看JNI,在其中回調(diào)了方法:“ void onExit(int pid, int exitValue);” 在方法中:

 
 
 
 
  1. void onExit(int pid, int exitValue) { 
  2.         ProcessReference processRefe
    網(wǎng)站題目:Process 創(chuàng)建+控制+分析 經(jīng)驗(yàn)淺談
    本文網(wǎng)址:http://m.5511xx.com/article/ccchepd.html