<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    中文JAVA技術平等自由協作創造

    Java專題文章博客和開源

    常用鏈接

    統計

    最新評論

    java中執行aapt命令行錯誤

      用java的Runtime.getRuntime()。exec(cmd)方式,執行aapt命令行解包apk文件時,遇到"Cannot allocate memory"的錯誤。

      但是直接在linux上使用aapt命令可以正常使用。

      網上查詢資料整理如下:

      Cannot allocate memory

      在Linux上調試一個比較復雜的Java程序,稱為JavaA吧,JavaA會頻繁的通過Process proc = Runtime.getRuntime()。exec(cmd);調用一些外部程序。在系統負載和該程序占用內存都比較大的情況下,會出現調用失敗的情況,錯誤信息是:"Cannot allocate memory".

      overcommit_memory

      通過top發現,JavaA大部分時間占用的內存實際并不多,但是占用的虛擬內存很大。馬上修改該程序啟動時的JVM參數,將最大內存調的小一些,果然就不出錯了。由于JavaA必須在內存中處理大量的數據,內存太小了就可能處理不了,因此這么改是不可行的。

      上網查的過程中,發現一些有趣的東西。Linux內核中可以設置內存的overcommit_memory屬性,意思是Linux內核認為有些程序很保守,總是申請較多的內存,但實際并不使用,因此在設置overcommit后,內核將不檢查剩余內存是否夠用,直接允許所有的內存分配。可能大部分情況下沒問題,但是仔細想想,還是有很大的問題,最嚴重的是改變了malloc的語義,調用者不能通過返回值來判斷內存是否分配成功了。另外一個問題是,萬一內存真的不夠了怎么辦?Linux中有個特殊的進程,OOM(out-of-memory)進程終止者,其功能就是在內存真的不夠時,隨機或者根據某些原則殺掉一些進程。選擇進程的原則好像不能精確控制,那將是一件很恐怖的事情…

      順道小小八卦一下,當時還有不少人研究如何選擇要殺掉的進程,提出了不少的改進方法,于是有人看不下去了,說了一個很有意思的故事,某航空公司為了節省油錢,每次飛行并不加滿油,飛行途中要是超員了就挑一些乘客扔下去,于是大家興高采烈的討論應該扔誰下去…

      Runtime.getRuntime()。exec(cmd)的執行流程分析

      繼續上網查,大概意思是Java程序調用外部程序時可能需要分配跟父進程同等大小的內存。這就奇怪了,比如說,我隨便調用一下ls命令,也需要很多內存嗎?肯定是Java調用外部程序的接口里處理比較特殊。嗯,

      剛好JDK也開源,看看源碼去。

      分析SUN JDK 1.5 SRC,找到Runtime.getRuntime()。exec(cmd)的執行流程:

      java.lang.Runtime.exec(cmd);

      --java.lang.ProcessBuilder.start();

      ----java.lang.ProcessImpl.start();

      ------Java_java_lang_UNIXProcess_forkAndExec() in j2se/src/solaris/native/java/lang

      /UNIXProcess_md.c

      --------1)。 fork(); 2)。 execvp();

      man fork知道,fork產生的子進程需要復制父進程在內存中的所有數據內容(代碼段、數據段、堆棧段),

      由于全部復制開銷較大,因此Linux已經采用copy-on-write機制,即只是復制頁表,共享內容,在有改變的時候再去申請內存和復制數據雅思答案

      因此我分析,問題的原因可能是這樣的,雖然Linux早已在fork()中采用copy-on-write機制,但是JVM調用fork()后,Java進程里的其它線程往往會被調度回來繼續執行,修改了自己的內存,而這個時候

      execvp()還沒有執行,于是悲劇就發生了,內存都要重新復制一遍。

      解決辦法

      最后說說解決辦法,既然問題出在可能會申請分配跟父進程同等大小的內存,那么我限制父進程使用的內存就可以了。前面說了我們正在開發的JavaA必須使用比較大的內存,可是JavaA不一定是父進程呀,我可以單獨運行一個Java程序,稱為JavaB吧,由它負責調用外部程序,JavaA調用我們封裝后的接口與之通信,等待外部程序結束,從而與Runtime.getRuntime()。exec(cmd)的語義保持一致。這個單獨運行的JavaB只需要很小很小的內存,因此不太可能出現無法分配內存,進而無法執行外部程序的問題了雅思改分

     

    posted on 2013-08-17 09:41 好不容易 閱讀(578) 評論(0)  編輯  收藏


    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    PK10開獎 PK10開獎
    主站蜘蛛池模板: 国产精品亚洲美女久久久| 免费看国产成年无码AV片| 久久99亚洲综合精品首页| 国产精品亚洲精品爽爽| 国产禁女女网站免费看| 麻豆亚洲AV成人无码久久精品 | 精品视频在线免费观看| 亚洲精品成人无限看| 久久久久久国产精品免费免费男同 | 亚洲乱码无人区卡1卡2卡3| 日韩精品成人无码专区免费| wwwxxx亚洲| 精品久久免费视频| 黄色网址在线免费观看| 精品亚洲视频在线观看| 久久久久久免费一区二区三区 | 亚洲视频无码高清在线| 最新中文字幕电影免费观看| 亚洲AV无码国产精品永久一区| 亚洲?V无码乱码国产精品| 国产免费内射又粗又爽密桃视频| 亚洲熟妇无码乱子AV电影| 亚洲视频在线免费观看| 亚洲免费观看在线视频| 免费看国产曰批40分钟| 思思久久99热免费精品6| 亚洲AV无码第一区二区三区| 最近中文字幕完整版免费高清| 欧洲 亚洲 国产图片综合| 又色又污又黄无遮挡的免费视| a一级毛片免费高清在线| 亚洲男人天堂av| 日本一道在线日本一道高清不卡免费| 无遮挡免费一区二区三区| 久久久久久久久亚洲| 毛片免费观看的视频| 精品乱子伦一区二区三区高清免费播放 | 一本久久综合亚洲鲁鲁五月天| 日本在线免费观看| 亚洲午夜精品一区二区麻豆| 亚洲午夜久久久久久久久电影网|