本文介绍了Linux JVM实际上是否实现了线程优先级?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

编写一个快速的Java proggy以产生每个优先级的10个线程,并使用BigDecimals计算pi(4 * atan(1)方法),每个BigDecimals 500,000次,连接每个线程并报告run方法的已用时间。是的,可能不是最好的例子,但保持基本。

Wrote a quick Java proggy to spawn 10 threads with each priority and calculate pi (4*atan(1) method) with BigDecimals 500,000 times each, join on each thread and report the elapsed time for run method. Yeah, prob'ly not the best example, but keeping it basic.

我知道

在C语言中这是非常重要的,但我们可以假设从来没有在Linux JVM上设置原生优先级?

It is non-trivial to do in C, but can we assume that native priorities are never set on Linux JVMs?

$uname -r && grep bogomips /proc/cpuinfo
2.4.33.3
bogomips        : 4312.26
$java -version 2>&1 |head -1
Java version "1.6.0_01"
$javac T.java && java -Xmx32m -XX:+UseThreadPriorities T
1:3112
2:2636
3:2662
4:3118
5:2870
6:3319
7:3412
8:3304
9:3299
10:3069

看起来没有人想到的偏差!那是在一台小型虚拟Linux机器上。也许只是Sun的?我们将尝试IBM J9 VM:

Looks like not much of a deviation that one would expect! That was on a small virtual Linux machine. Maybe just Sun's? We shall try IBM J9 VM:

1:4091
2:4142
3:3957
4:3905
5:3984
6:3985
7:4130
8:4055
9:3752
10:4071

相比之下,总数看起来相当不错,但从线程优先级角度看,数字没有规模。

The gross numbers look pretty good in comparison, but there is no scale to the numbers from a thread priority perspective.

让我们尝试使用旧版Sun JVM在2.6内核上进行500k次迭代,其中一个常常加载的平均负载很少低于7:

Let's try 500k iterations on a 2.6 kernel with an older Sun JVM, one that is constantly loaded with load averages rarely below 7:

$uname -r && grep bogomips /proc/cpuinfo
2.6.9-67.ELsmp
bogomips        : 3992.93
bogomips        : 3990.00
$java -version 2>&1 |head -1
java version "1.4.2_14"
$javac T.java && java -Xmx32m -XX:+UseThreadPriorities T
1:63200
2:64388
3:62532
4:58529
5:62292
6:64872
7:64885
8:64584
9:61653
10:61575

让我们尝试使用2.6内核的真正平板上的IBM J9,因为更大的系统我会将迭代次数增加到2,000,000。

Let's try IBM's J9 on a real slab just with 2.6 kernel and since a bigger system I'll increase iterations to 2,000,000.

$uname -r && grep bogomips /proc/cpuinfo
2.6.9-78.ELsmp
bogomips        : 5989.03
bogomips        : 5985.03
bogomips        : 5985.01
bogomips        : 5985.02
bogomips        : 5984.99
bogomips        : 5985.02
bogomips        : 5984.99
bogomips        : 5985.02
$java -Xmx32m T # this is the IBM J9
1:1718
2:1569
3:1989
4:1897
5:1839
6:1688
7:1634
8:1552
9:2027
10:1522

有些好时光,但仍然没有明显的线程/进程优先级。

Some great times, but still no apparent thread/process priorities.

让我们试试一个Windows框。我知道Windows有一个相当激进的线程优先级方案。任何高于正常的传闻都会消耗得更多。因此,让我们在每个线程中进行900,000次迭代:

Let's try a Windows box. I know that Windows has a fairly aggressive thread priority scheme. Anything above normal anecdotaly consumes much more. As such, let's move to 900,000 iterations in each thread:

C:\>java -version
java version "1.6.0_11"
C:\>java -Xmx32m T
1:12578
2:12625
3:11469
4:11453
5:10781
6:8937
7:10516
8:8406
9:9953
10:7391

我们正在寻找什么,不是吗?

Very much what we're looking for, no?

所以Linux JVM显然没有线程优先级?我知道你不能真正降低C级的低级别,但我认为JVM工程师会想出如何保持一个低级别的调度程序。

So Linux JVM's apparently don't have thread priority? I understand that you can't really renice to a lower nice level in C, but I would assume JVM engineers would have figured out how to keep a low-niced dispatcher of sorts.

推荐答案

好吧,让我们来看看:

2947行:

////////////////////////////////////////////////////////////////////////////////
// thread priority support

// Note: Normal Linux applications are run with SCHED_OTHER policy. SCHED_OTHER
// only supports dynamic priority, static priority must be zero. For real-time
// applications, Linux supports SCHED_RR which allows static priority (1-99).
// However, for large multi-threaded applications, SCHED_RR is not only slower
// than SCHED_OTHER, but also very unstable (my volano tests hang hard 4 out
// of 5 runs - Sep 2005).
//
// The following code actually changes the niceness of kernel-thread/LWP. It
// has an assumption that setpriority() only modifies one kernel-thread/LWP,
// not the entire user process, and user level threads are 1:1 mapped to kernel
// threads. It has always been the case, but could change in the future. For
// this reason, the code should not be used as default (ThreadPriorityPolicy=0).
// It is only used when ThreadPriorityPolicy=1 and requires root privilege.

...

第2982行:

 static int prio_init() {
   if (ThreadPriorityPolicy == 1) {
     // Only root can raise thread priority. Don't allow ThreadPriorityPolicy=1
     // if effective uid is not root. Perhaps, a more elegant way of doing
     // this is to test CAP_SYS_NICE capability, but that will require libcap.so
     if (geteuid() != 0) {
       if (!FLAG_IS_DEFAULT(ThreadPriorityPolicy)) {
         warning("-XX:ThreadPriorityPolicy requires root privilege on Linux");
       }
       ThreadPriorityPolicy = 0;
     }
   }
   return 0;
 }

...

第2997行:

OSReturn os::set_native_priority(Thread* thread, int newpri) {
  if ( !UseThreadPriorities || ThreadPriorityPolicy == 0 ) return OS_OK;

  int ret = setpriority(PRIO_PROCESS, thread->osthread()->thread_id(), newpri);
  return (ret == 0) ? OS_OK : OS_ERR;
}

所以!至少在Sun Java上,在Linux上,你不会看到线程优先级,除非你已经完成了 -XX:ThreadPriorityPolicy ,这似乎需要root。

So! At least on Sun Java, on Linux, you won't see thread priorities unless you have done -XX:ThreadPriorityPolicy and that seems to require root.

这篇关于Linux JVM实际上是否实现了线程优先级?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-27 08:16