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;
}
--- 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;
}
相关文章推荐
- Android手机出现android.process.media进程意外停止的解决办法(图文)
- hbase集群中的从节点的Hregionserver进程出现闪退现象解决办法
- eclipse 直接运行系统级应用(含android.uid.system)出现 INSTALL_FAILED_SHARED_USER_INCOMPATIBLE解决办法
- 编译Android系统AIDL模块出现couldn't find import for class错误的解决办法
- Android源码解析之(九)-->SystemServer进程启动流程
- Android Studio升级到3.3出现的问题-手动解决办法
- Android出现“Read-only file system”解决办法
- 【Android杂谈】图片出现OOM解决办法总结
- Android中 在显示ImageView时图片上面和下面都出现一段空白区间的解决办法
- 关于vsftp出现Restarting vsftpd (via systemctl): Job for vsftpd.service failed because the control 的解决办法
- Android之jni编译出现error: jump to label ‘XXXX’ [-fpermissive]解决办法
- Android启动界面先白屏或者黑屏然后才出现画面的解决办法
- Print2Flash出现"System Error. Code:1722. RPC服务器不可用."错误解决办法
- Android项目导入时,出现的Could not write file 。。。。。。.classpath错误解决办法
- Android 出现:java.lang.NoClassDefFoundError...错误解决办法
- Android手机出现"已安装了存在签名冲突的同名数据包"的原因及解决办法
- 使用Bitmap.FromStream(GetType().Assembly.GetManifestResourceStream())出现System.ArgumentException的解决办法
- keil编译出现Warning: L6304W: Duplicate input file .\output\system_stm32f2xx_1.o ignored.解决办法
- Android项目运行junit测试类时出现错误Internal Error (classFileParser.cpp:3494)的解决办法
- Visual Studio 2008不能创建数据库连接出现:未能加载文件或程序集“Microsoft.SqlServer.Management.Sdk.Sfc, Version=10.0.0.0, Culture=neutral,PublicKeyToken=89845dcd8080cc91”或它的一个依赖项。系统找不到指定的文件的解决办法