Java runtime.getruntime(cmd.exe c () error: Cannot allocate memory!

Source: Internet
Author: User

When Java's runtime.getruntime(cmd.exe c (cmd) method is used to unpackage the apk file through the aapt command line, the error "Cannot allocate memory" is encountered. However, the aapt command can be used normally directly in linux. Query Information on the Internet as follows: Cannot allocate memory has a complicated Java program called JavaA in Linux. JavaA will frequently use Process proc = runtime.getruntime(cmd.exe c (cmd ); call some external programs. When the system load and the program occupy a large amount of memory, the call may fail. The error message is "Cannot allocate memory ". Overcommit_memory found through top that JavaA occupied a small amount of memory most of the time, but occupied a large amount of virtual memory. Immediately modify the JVM parameter when the program starts, and tune the maximum memory to a smaller value, so there is no error. Because JavaA must process a large amount of data in the memory, it cannot be processed if the memory is too small, so this change is not feasible. Some interesting things are found during online queries. In the Linux kernel, you can set the overcommit_memory attribute of the memory, which means that some programs in the Linux kernel are very conservative and always apply for a large amount of memory, but they are not actually used. Therefore, after overcommit is set, the kernel will not check whether the remaining memory is sufficient, and allow all memory allocation directly. There may be no problem in most cases, but think about it carefully. The most serious problem is that the malloc semantics is changed. The caller cannot determine whether the memory allocation is successful by returning the value. Another problem is, what should I do if the memory is insufficient? There is a special process in Linux. The out-of-memory process Terminator is capable of killing some processes randomly or in accordance with certain principles when the memory is really insufficient. The process selection principle seems to be unable to be precisely controlled, which is a terrible thing... By the way, there were still a lot of people studying how to choose the process to be killed and put forward a lot of improvement methods. So some people couldn't see it anymore and told a very interesting story, in order to save fuel money, an airline does not fill up the fuel for each flight. If it is a super member during the flight, it will pick some passengers and throw them down. So everyone will happily discuss who to throw... The Execution Process Analysis of runtime.getruntime(cmd.exe c (cmd) continues online query. This probably means that when a Java program calls an external program, it may need to allocate the same size of memory as the parent process. This is strange. For example, do I need a lot of memory to call the ls command? It must be special for Java to call external program interfaces. Well, JDK is also open-source. Let's look at the source code. Analyze sun jdk 1.5 srcand find the execution process of runtime.getruntime(cmd.exe c (cmd): java.lang.Runtime.exe c (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 knows that the child process generated by fork needs to copy all the data content of the parent process in the memory (code segment, data segment, and stack segment). Because of the high overhead of all replication, therefore, Linux has adopted the copy-on-write mechanism, that is, only copying the page table and sharing the content. When the change occurs, apply for memory and copy data. Therefore, I analyzed the cause of the problem. Although Linux has already adopted the copy-on-write mechanism in fork (), after the JVM calls fork, other threads in the Java Process are often scheduled to run back and modify their memory. At this time, execvp () has not been executed, so the tragedy has occurred, the memory must be replicated again. Solution: Finally, let's talk about the solution. Since the problem is that the application may allocate the same size of memory as the parent process, I can limit the memory used by the parent process. As mentioned above, the JavaA we are developing must use relatively large memory, but JavaA is not necessarily a parent process. I can run a Java program called JavaB separately, it is responsible for calling external programs, and JavaA calls the encapsulated interface to communicate with it. It waits for the external program sequence to begin, and is consistent with the semantics of runtime.getruntime(.exe c (cmd. This Independently Running JavaB only requires a small amount of memory, so it is unlikely that memory cannot be allocated and external programs cannot be executed.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.