您的位置:首页 > 移动开发 > Android开发

android 4.X上偶尔出现的多个system_server进程的解决办法

2014-01-22 10:20 309 查看
在android 4.X中有时候会出现多个system_server进程,会导致系统内存占用急速增加,系统性能下降的情况,可以尝试如下修正方法:

--- java_lang_ProcessManager.cpp
+++ java_lang_ProcessManager_new.cpp
@@ -23,7 +23,7 @@
#include <stdlib.h>
#include <string.h>
#include <errno.h>
-
+#include <sys/wait.h>
#include "jni.h"
#include "JNIHelp.h"
#include "JniConstants.h"
@@ -60,6 +60,19 @@
}
}

+#define TEMP_FAILURE_RETRY(exp) ({ \
+ typeof (exp) _rc; \
+ do { \
+ _rc = (exp); \
+ } while (_rc == -1 && errno == EINTR); \
+ _rc; })
+
+static void AbortChild(int status_pipe_fd) {
+ int error = errno;
+ TEMP_FAILURE_RETRY(write(status_pipe_fd, &error, sizeof(int)));
+ close(status_pipe_fd);
+ _exit(127);
+}
/** Executes a command in a child process. */
static pid_t executeProcess(JNIEnv* env, char** commands, char** environment,
const char* workingDirectory, jobject inDescriptor,
@@ -129,7 +142,7 @@
// Switch to working directory.
if (workingDirectory != NULL) {
if (chdir(workingDirectory) == -1) {
- goto execFailed;
+ AbortChild(statusOut);
}
}

@@ -143,13 +156,7 @@
// should be the command itself. In fact, I get segfaults when this
// isn't the case.
execvp(commands[0], commands);
-
- // If we got here, execvp() failed or the working dir was invalid.
-execFailed:
- int error = errno;
- write(statusOut, &error, sizeof(int));
- close(statusOut);
- exit(error);
+ AbortChild(statusOut);
}

// This is the parent process.
@@ -163,16 +170,22 @@
// Check status pipe for an error code. If execvp() succeeds, the other
// end of the pipe should automatically close, in which case, we'll read
// nothing.
- int result;
- int count = read(statusIn, &result, sizeof(int));
+ int child_errno;
+ ssize_t count = TEMP_FAILURE_RETRY(read(statusIn, &child_errno, sizeof(int)));
close(statusIn);
if (count > 0) {
- jniThrowIOException(env, result);
+ jniThrowIOException(env, child_errno);

close(stdoutIn);
close(stdinOut);
close(stderrIn);

+ // Reap our zombie child right away
+ int status;
+ int rc = TEMP_FAILURE_RETRY(waitpid(childPid, &status, 0));
+ if(rc == -1) {
+ ALOGW("waitpid on failed exec failed: %s", strerror(errno));
+ }
return -1;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐