[Java Performance] JVM 线程调优

调整线程栈空间

当非常缺少内存时,可以调整线程使用的内存。每个线程都有一个栈,用来记录该线程的调用栈信息。线程中的栈的默认空间是有OS和JVM的版本决定的:

OS 32-bit 64-bit
Linux 320 KB 1 MB
Mac OS N/A 1 MB
Solaris Sparc 512 KB 1 MB
Solaris X86 320 KB 1 MB
Windows 320 KB 1 MB

当栈空间被设置的过小时,可能会因为有较长的调用栈而抛出StackOverflowError。

在64位的JVM中,一般不需要修改这个值,除非内存确实非常吃紧。而在32位的JVM中,可以将这个值从320KB设置成128KB,为了给堆内存腾出更多的空间。

更改线程栈空间的指令:-Xss=N 比如:-Xss=256k

偏见锁(Biased
Locking)

当锁被多个线程所争夺时,JVM和OS能够选择将锁分配给哪个线程。可以使用一种公平的策略将锁分配给其他线程,或者也可以使用一种不公平(偏见)的策略,比如将锁再分配给上一次拥有该锁的线程。

将锁再次分配给上一次拥有该锁的线程,这样做的合理性在于:由于时间上的连续性,处理器中可能还缓存着和该线程所执行任务相关的数据,因此当线程再次执行时,准备上下文的时间就能够节省下来。当然,使用偏见锁本身需要记录一些相关数据,因此在某些时候反而会对性能有影响。

典型的比如,在很多时候,如果将偏见锁应用在线程池中,那么性能反而会变差。如果一个应用并不需要使用偏见锁来作为锁分配的策略,那么可以通过:-XX:-UseBiasedLocking 来禁用它,因为默认是会启用偏见锁的,禁用它会提升些许性能。

锁的自旋(Lock
Spinning)

对于没有得到锁的线程,JVM有两种处理方式:

  • 让线程进入一个忙循环(Busy Loop),待它执行了一些指令后会再次检查需要的锁是否可用。
  • 让线程进入一个队列,当需要的锁可用时通知它。此时CPU可以被其它线程使用。

如果处于竞争中的锁只需要被持有一小段时间,那么使用第一种忙循环(也被称为线程自旋(Thread Spinning))的速度会比第二种让线程进入队列的方式快的多。反之,当竞争中的锁会被线程持有较长的时间时,使用第二种方式更优,这能够让CPU的有效利用率更高。

JVM会合理地选择使用哪种处理方式。首先会让线程自旋一段时间,如果还没有得到需要的锁,就会将该线程放入队列中等待,从而让出CPU资源给其它线程。

线程优先级

在Java API中,每个线程都可以被设置一个优先级,OS会参考这个值。但是注意OS仅仅是“参考”,并不一定会遵循它。OS会对每个运行中的线程计算一个“当前”优先级。这个计算过程会考虑到设置的优先级,但是它仅仅是众多因素中的一个,其中最重要的因素往往是这个线程已经运行了多长时间。考虑这个因素是为了让每个线程都能够得到运行的机会。所以,无论线程被设置的优先级有多低,它们也总能够得到运行的机会。

另外,设置的线程优先级在不同的OS上的权重是不同的。在基于Unix的系统上,线程的执行时间是主导线程当前优先级的因素,也就是说设置的线程优先级几乎不会被“参考”。而在Windows系统上,设置的线程优先级的权重会稍微高一些。

所以,无论是在哪个OS上,应用的性能都不能依赖于对线程设置优先级。如果某些任务的优先级确实高于另外一些任务,那么这一点需要被应用程序的逻辑来完成,而不是通过设置线程的优先级来完成。

一个办法将任务分配给不同的线程池,然后设置这些线程池的规模。

时间: 2024-09-30 07:37:50

[Java Performance] JVM 线程调优的相关文章

Java架构师面试题——JVM性能调优

JVM内存调优 对JVM内存的系统级的调优主要的目的是减少GC的频率和Full GC的次数. 1.Full GC 会对整个堆进行整理,包括Young.Tenured和Perm.Full GC因为需要对整个堆进行回收,所以比较慢,因此应该尽可能减少Full GC的次数. 2.导致Full GC的原因 1)年老代(Tenured)被写满 调优时尽量让对象在新生代GC时被回收.让对象在新生代多存活一段时间和不要创建过大的对象及数组避免直接在旧生代创建对象 . 2)持久代Pemanet Generati

深入理解Java虚拟机(jvm性能调优+内存模型+虚拟机原理)视频教程

14套java精品高级架构课,缓存架构,深入Jvm虚拟机,全文检索Elasticsearch,Dubbo分布式Restful 服务,并发原理编程,SpringBoot,SpringCloud,RocketMQ中间件,Mysql分布式集群,服务架构,运 维架构视频教程 14套精品课程介绍: 1.14套精 品是最新整理的课程,都是当下最火的技术,最火的课程,也是全网课程的精品: 2.14套资 源包含:全套完整高清视频.完整源码.配套文档: 3.知识也 是需要投资的,有投入才会有产出(保证投入产出比是

JVM性能调优监控工具jps、jstack、jmap、jhat、jstat、hprof使用详解

现实企业级Java开发中,有时候我们会碰到下面这些问题: OutOfMemoryError,内存不足 内存泄露 线程死锁 锁争用(Lock Contention) Java进程消耗CPU过高 ...... 这些问题在日常开发中可能被很多人忽视(比如有的人遇到上面的问题只是重启服务器或者调大内存,而不会深究问题根源),但能够理解并解决这些问题是Java程序员进阶的必备要求.本文将对一些常用的JVM性能调优监控工具进行介绍,希望能起抛砖引玉之用.本文参考了网上很多资料,难以一一列举,在此对这些资料的

[转]JVM性能调优监控工具

http://my.oschina.net/feichexia/blog/196575?p=1#comments JDK本身提供了很多方便的JVM性能调优监控工具,除了集成式的VisualVM和jConsole外,还有jps.jstack.jmap.jhat.jstat.hprof等小巧的工具,本博客希望能起抛砖引玉之用,让大家能开始对JVM性能调优的常用工具有所了解. 现实企业级Java开发中,有时候我们会碰到下面这些问题: OutOfMemoryError,内存不足 内存泄露 线程死锁 锁争

JVM性能调优监控工具jps、jstack、jmap、jhat、jstat使用详解

JDK本身提供了很多方便的JVM性能调优监控工具,除了集成式的VisualVM和jConsole外,还有jps.jstack.jmap.jhat.jstat等小巧的工具,本博客希望能起抛砖引玉之用,让大家能开始对JVM性能调优的常用工具有所了解. 现实企业级Java开发中,有时候我们会碰到下面这些问题: OutOfMemoryError,内存不足 内存泄露 线程死锁 锁争用(Lock Contention) Java进程消耗CPU过高 ...... 这些问题在日常开发中可能被很多人忽视(比如有的

JVM性能调优监控工具jps、jstack、jmap、jhat、jstat使用详解(转VIII)

JDK本身提供了很多方便的JVM性能调优监控工具,除了集成式的VisualVM和jConsole外,还有jps.jstack.jmap.jhat.jstat等小巧的工具,本博客希望能起抛砖引玉之用,让大家能开始对JVM性能调优的常用工具有所了解. 现实企业级Java开发中,有时候我们会碰到下面这些问题: OutOfMemoryError,内存不足 内存泄露 线程死锁 锁争用(Lock Contention) Java进程消耗CPU过高 ...... 这些问题在日常开发中可能被很多人忽视(比如有的

JVM 性能调优实战之:一次系统性能瓶颈的寻找过程

玩过性能优化的朋友都清楚,性能优化的关键并不在于怎么进行优化,而在于怎么找到当前系统的性能瓶颈.性能优化分为好几个层次,比如系统层次.算法层次.代码层次...JVM 的性能优化被认为是底层优化,门槛较高,精通这种技能的人比较少.笔者呆过几家技术力量不算弱的公司,每个公司内部真正能够进行 JVM 性能调优的人寥寥无几.甚至没有.如是乎,能够有效通过 JVM 调优提升系统性能的人往往被人们冠以"大牛"."大师"之类的称呼.其实 JVM 本身给我们提供了很多强大而有效的监

JVM性能调优1:JVM性能调优理论及实践(收集整理)

本系列包括: JVM性能调优1:JVM性能调优理论及实践(收集整理) JVM性能调优2:JVM性能调优参数整理 JVM性能调优3:JVM_堆溢出分析过程和命令 JVm性能调优4:GC日志分析 JVM性能调优5:Heap堆分析方法 注:本文部分内容收集整理了网上的资料. 1.      内存结构 1.1.     分代结构图 注意: 在JVM中,非堆内存,根据模式不同分为不同的几个部分. -Server下:非堆包括:持久代和代码缓存(Code cache) -client下:非堆包括:持久代.代码

(转)JVM性能调优监控工具jps、jstack、jmap、jhat、jstat、hprof使用详解

转:https://my.oschina.net/feichexia/blog/196575?p=3 现实企业级Java开发中,有时候我们会碰到下面这些问题: OutOfMemoryError,内存不足 内存泄露 线程死锁 锁争用(Lock Contention) Java进程消耗CPU过高 ...... 这些问题在日常开发中可能被很多人忽视(比如有的人遇到上面的问题只是重启服务器或者调大内存,而不会深究问题根源),但能够理解并解决这些问题是Java程序员进阶的必备要求.本文将对一些常用的JVM