难道Linux的JVM的实际执行线程的优先级?(Do Linux JVMs actually imp

2019-09-07 02:06发布

写了一个快速的Java proggy产卵10个线程,每个优先级和计算圆周率(4 * ATAN(1)方法)与BigDecimals的每50万次,参加每个线程和报告run方法所经过的时间。 是啊,prob'ly不是最好的例子,但保持它的基本。

我所知道的Bug4813310

这是不平凡的C ++做的,但是我们可以假设,本地优先级是从来没有在Linux上的JVM?

$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:

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

毛数字看起来还不错的比较,但还没有形成规模,从一个线程优先级的角度的数字。

让我们尝试,在2.6内核与旧了Sun JVM,一个是不断地加载的平均负载很少低于7 500K迭代:

$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

让我们尝试了IBM的一个真正的平板J9只是2.6内核,因为一个更大的系统,我会增加迭代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

一些伟大的时代,但仍没有明显的线程/进程的优先级。

让我们尝试Windows中。 我知道,Windows有一个相当积极线程优先级方案。 任何高于正常 anecdotaly消耗更多。 因此,让我们继续在每个线程900000次迭代:

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

很多东西我们要找的,不是吗?

因此Linux JVM的显然不具备线程的优先级? 据我所知,你不能真正使用renice在C较低不错的水平,但我会假设JVM工程师们已经找到了如何保持某种形式的低niced调度。

Answer 1:

好吧,让我们来看看源 :

行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。



Answer 2:

默认的Linux线程调度策略SCHED_OTHER不支持优先级。 或者更确切地说,它支持优先级设置一个值:0,另外所谓的“实时”的政策SCHED_FIFO和SCHED_RR支持更高的优先级,但仅适用于具有超级用户权限的进程。



Answer 3:

只是一个镜头在这里暗,但不会有JVM中的优先级线程需要有调整的操作系统线程的优先级的能力吗?

Linux(和类Unix任何OS)限制,得到处理更高的优先级,以根的能力。 我想会有上线了类似的限制。



文章来源: Do Linux JVMs actually implement Thread priorities?