java - 阻止java程序打开线程

标签 java multithreading jvm execve setrlimit

我正在尝试运行一个java应用程序,更具体地说是一个jar编译的应用程序,在c中使用execve()
像这样的东西:

char *cmd[] = {"a.jar"};
execve("a.jar",cmd,NULL);

工作正常,但是当我尝试使用类似的方法限制该程序可以打开的线程数时:

struct rlimit rlp;
rlp.rlim_cur = rlp.rlim_max = limit_nproc; 
setrlimit(RLIMIT_NPROC,&rlp);

我的 JVM 存在问题,它会打开线程,但我正在阻止这种情况发生,因此出现此错误:

java.lang.OutOfMemoryError: Cannot create GC thread. Out of system resources.

如何阻止在 java 应用程序中打开的线程,而不是 JVM 打开的线程? !

请注意,问题是如何阻止用户线程而不是系统线程,我需要对运行环境进行限制,就像我在第二个代码“RLIMIT_NPROC”中所做的那样

谢谢!

最佳答案

这可以通过 JVMTI 来实现代理。

这个想法是拦截 native Thread.start0() 方法并在调用时抛出异常。

这是一个用 C++ 编写的示例代理:

#include <jvmti.h>

// Original native implementation of Thread.start0(), if you wish to call it
extern "C" void JNICALL JVM_StartThread(JNIEnv* env, jthread thread);

void JNICALL StartThreadHook(JNIEnv* env, jthread thread) {
    env->ThrowNew(env->FindClass("java/lang/Error"), "Threads forbidden");
}

void JNICALL VMInit(jvmtiEnv* jvmti, JNIEnv* env, jthread thread) {
    // After VM is initialized, intercept Thread.start0() with our hook function
    jclass thread_class = env->FindClass("java/lang/Thread");
    JNINativeMethod start0 = {(char*)"start0", (char*)"()V", (void*)StartThreadHook};
    env->RegisterNatives(thread_class, &start0, 1);
}

JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM* vm, char* options, void* reserved) {
    jvmtiEnv* jvmti;
    vm->GetEnv((void**)&jvmti, JVMTI_VERSION_1_0);

    jvmtiEventCallbacks callbacks = {0};
    callbacks.VMInit = VMInit;
    jvmti->SetEventCallbacks(&callbacks, sizeof(callbacks));
    jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_VM_INIT, NULL);

    return 0;
}

编译代理:

g++ -fPIC -shared -olibnothreads.so -Wl,-soname,libnothreads.so nothreads.cpp

使用代理运行应用程序:

java -agentpath:/path/to/libnothreads.so -jar app.jar

请注意,您还可以使用 JVMTI 来实现何时允许以及何时拒绝启动新线程的自定义逻辑。例如,ThreadStartThreadEnd事件将有助于计算创建的线程。 GetStackTrace函数将有助于查找哪些类正在尝试创建线程。

关于java - 阻止java程序打开线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37701164/

相关文章:

java - 为什么消费者线程只有在生产者写完10个对象后才执行

java - 如果用户计算机上未安装 Java,如何在 JAR 文件中包含 JVM?

java - 异常 java.lang.NoClassDefFoundError : com. google.android.gms.common.AccountPicker

java - 单击后如何在 actionPerformed 内创建标签?

java - 无法在我的车辆交易程序中销售卡车和 1 个 JUnit 错误(缺少抽象方法)

java - 使用 freemarker 配置构建代码时出现 ClassNotFoundException : freemarker. cache.TemplateLoader --updated

c# - SynchronizationContext.Current 在主线程上为空

java - ScheduledThreadPoolExecutor.remove : Is it safe to use

java - 2 个不同的 eclipse 安装是否使用不同的 JVM?

grails - Groovy & Grails 中的方法代码太大?