简体   繁体   English

如何更改正在运行的 java 进程的优先级?

[英]How to change the priority of a running java process?

In a related question we explored using ProcessBuilder to start external processes in low priority using OS-dependant commands.在一个相关问题中,我们探索了使用 ProcessBuilder 使用依赖于操作系统的命令以低优先级启动外部进程。 I also discovered that if a parent process is low priority, then all of its spawned processes start in low priority.我还发现,如果父进程是低优先级的,那么它的所有衍生进程都以低优先级启动。 So my new question is about starting a java file (run via double-clicking an executable jar in windows) in low priority or changing its priority programmatically during the run.所以我的新问题是关于以低优先级启动 java 文件(通过双击 Windows 中的可执行 jar 运行)或在运行期间以编程方式更改其优先级。 I have tried altering the thread priority, but this has no effect on the windows process priority.我试过改变线程优先级,但这对 windows 进程优先级没有影响。

I have tried the following, but it does not change the process priority in the task manager我已经尝试了以下,但它不会改变任务管理器中的进程优先级

public class hello{
    public hello(){
        try{
            Thread.currentThread().setPriority(1);
            Thread.sleep(10000);    
        }catch(Exception e){e.printStackTrace();}
    }
}

The only other thing I can think of is to run the program using a batch file, but I would rather keep this in the family so to speak.我能想到的唯一另一件事是使用批处理文件运行程序,但可以这么说,我宁愿把它留在家里。 So does anyone know of a java-based way to change the current process priority?那么有没有人知道基于java的方法来改变当前进程的优先级? Ideally, it would be nice to be able to change the priority of the process in response to user input while the program is running.理想情况下,如果能够在程序运行时响应用户输入来更改进程的优先级,那就太好了。

Perhaps you are trying to do something the OS does for you.也许您正在尝试为操作系统做一些事情。

In Unix, under load, each process is given a short time slice to do its work.在 Unix 中,在负载下,每个进程都有一个短时间片来完成其工作。 If it uses all its time slice it is assume the process is CPU bound it priority is lowers.如果它使用了所有时间片,则假定该进程受 CPU 限制,它的优先级较低。 If it blocks on IO, it is assumed to be IO bound and its priority is raised (because it didn't use all its time slice)如果它在 IO 上阻塞,则假定它是 IO 绑定的并且它的优先级被提高(因为它没有使用它的所有时间片)

All this only matters if there isn't enough CPU.所有这些只有在没有足够的 CPU 时才重要。 If you keep you CPU load below 100% most of the time, every process will get as much CPU as it needs and the priority doesn't make much difference.如果您在大多数情况下将 CPU 负载保持在 100% 以下,那么每个进程都会获得所需的 CPU,并且优先级不会有太大的区别。

https://stackoverflow.com/questions/257859 discusses how to change the priority of a thread in Windows. https://stackoverflow.com/questions/257859讨论了如何在 Windows 中更改线程的优先级。 I don't know of any Java API to do this, so you're going to have to fall back on JNI to call into the Windows API. I don't know of any Java API to do this, so you're going to have to fall back on JNI to call into the Windows API. In your shoes I think I'd start with JNA which will let you map the functions easily, or find a ready-written Java wrapper to the API if there is one.在你的鞋子里,我想我会从JNA开始,它可以让你轻松地使用 map 功能,或者找到一个现成的 Java 包装器到 API 如果有的话。

(The title does not address windows specifically, but the tags do. However I think it might be relevant to know the differences.) (标题没有专门针对 windows,但标签确实如此。但是我认为了解这些差异可能是相关的。)

In general scheduling of threads an processes is a kernel dependent feature, there is hardly a portable way to do this.一般来说,进程的线程调度是 kernel 依赖的特性,几乎没有可移植的方法来做到这一点。 In fact what priority means varies greatkly.事实上,优先级的含义差别很大。 For example on NT a high value of 24 means realtime and a value of 1 means idle.例如,在 NT 上,高值 24 表示实时,值 1 表示空闲。 On unix this is the opposite: 1 is fastest and larger values are slower.在 unix 上,情况正好相反:1 最快,值越大越慢。

Of course Java abstracts this information away using .setPriority with a range of 1 ( lowest ) to 10 ( highest ).当然,Java 使用.setPriority将这些信息抽象出来,范围为 1( 最低)到 10( 最高)。

Something not pointed out yet, but a pretty big problem on many unixes is: By default a user can not increase the priority of a process (that is reduce the nice value), even if the user itself decreased the priority right before.还没有指出,但在许多 unix 上一个相当大的问题是:默认情况下,用户不能提高进程的优先级(即降低 nice 值),即使用户自己之前降低了优先级。

In contrast on NT I think you can reraise your priority back to default priority.相比之下,在 NT 上,我认为您可以将优先级重新提高到默认优先级。

Simply put: .setPriority may work on windows, but will most likely not work on unix.简单地说: .setPriority可能适用于 windows,但很可能不适用于 unix。

For Windows 10, you can still set low priority to the runninng process by deprecated WMIC command:对于 Windows 10,您仍然可以通过弃用的 WMIC 命令将运行进程设置为低优先级:

static void setSelfLowPrio(){
    try {
        Runtime.getRuntime()
                .exec(String.format("wmic process where processid=%d CALL setpriority \"idle\"", ProcessHandle.current().pid()));
    } catch (IOException e) {
        e.printStackTrace();
    }
}

You can also set it to "low" or "below normal" if "idle" is not enough for your process.如果“空闲”不足以满足您的流程,您也可以将其设置为“低”或“低于正常”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM