原文链接

现在多核CPU是主流。利用多核技术,可以有效发挥硬件的能力,提升吞吐量,对于Java程序,可以实现并发垃圾收集。但是Java利用多核技术也带来了一些问题,主要是多线程共享内存引起了。目前内存和CPU之间的带宽是一个主要瓶颈,每个核可以独享一部分高速缓存,可以提高性能。JVM是利用操作系统的“轻量级进程”实现线程,所以线程每操作一次共享内存,都无法在高速缓存中命中,是一次开销较大的系统调用。所以区别于普通的优化,针对多核平台,需要进行一些特殊的优化。

  代码优化

  线程数要大于等于核数

  如果使用多线程,只有运行的线程数比核数大,才有可能榨干CPU资源,否则会有若干核闲置。要注意的是,如果线程数目太多,就会占用过多内存,导致性能不升反降。JVM的垃圾回收也是需要线程的,所以这里的线程数包含JVM自己的线程。

  尽量减少共享数据写操作

  每个线程有自己的工作内存,在这个区域内,系统可以毫无顾忌的优化,如果去读共享内存区域,性能也不会下降。但是一旦线程想写共享内存(使用volatile关键字),就会插入很多内存屏障操作(Memory Barrier或者Memory Fence)指令,保证处理器不乱序执行。相比写本地线程自有的变量,性能下降很多。处理方法是尽量减少共享数据,这样也符合”数据耦合”的设计原则。

  使用synchronize关键字

  在Java1.5中,synchronize是性能低效的。因为这是一个重量级操作,需要调用操作接口,导致有可能加锁消耗的系统时间比加锁以外的操作还多。相比之下使用Java提供的Lock对象,性能更高一些。但是到了Java1.6,发生了变化。synchronize在语义上很清晰,可以进行很多优化,有适应自旋,锁消除,锁粗化,轻量级锁,偏向锁等等。导致在Java1.6上synchronize的性能并不比Lock差。官方也表示,他们也更支持synchronize,在未来的版本中还有优化余地。

  使用乐观策略

  传统的同步并发策略是悲观的。表现语义为:多线程操作一个对象的时候,总觉得会有两个线程在同时操作,所以需要锁起来。乐观策略是,假设平时就一个线程访问,当出现了冲突的时候,再重试。这样更高效一些。Java的AtomicInteger就是使用了这个策略。

  使用线程本地变量(ThreadLocal)

  使用ThreadLocal可以生成线程本地对象的副本,不会和其他线程共享。当该线程终止的时候,其本地变量可以全部回收。

  类中Field的排序

  可以将一个类会频繁访问到的几个field放在一起,这样他们就有更多的可能性被一起加入高速缓存。同时最好把他们放在头部。基本变量和引用变量不要交错排放。

  批量处理数组

  现在处理器可以用一条指令来处理一个数组中的多条记录,例如可以同时向一个byte数组中读或者写store记录。所以要尽量使用System.arraycopy ()这样的批量接口,而不是自己操作数组。

  JVM优化

  启用大内存页

  现在一个操作系统默认页是4K。如果你的heap是4GB,就意味着要执行1024*1024次分配操作。所以最好能把页调大。这个配额设计操作系统,单改 Jvm 是不行的。Linux上的配置有点复杂,不详述。

  在Java1.6中UseLargePages是默认开启的,LasrgePageSzieInBytes被设置成了4M。笔者看到一些情况下配置成了128MB,在官方的性能测试中更是配置到256MB。

  启用压缩指针

  Java的64的性能比32慢,原因是因为其指针由32位扩展到64位,虽然寻址空间从4GB扩大到256 TB,但导致性能的下降,并占用了更多的内存。所以对指针进行压缩。压缩后的指针最多支持32GB内存,并且可以获得32位JVM的性能。

  在JDK6 update 23默认开启了,之前的版本可以使用-XX:+UseCompressedOops来启动配置。

  性能可以看这个评测,性能的提升是很可观。

  启用NUMA

  numa是一个CPU的特性。SMP架构下,CPU的核是对称,但是他们共享一条系统总线。所以CPU多了,总线就会成为瓶颈。在NUMA架构下,若干CPU组成一个组,组之间有点对点的通讯,相互独立。启动它可以提高性能。

  NUMA需要硬件,操作系统,JVM同时启用,才能启用。Linux可以用numactl来配置numa,JVM通过-XX:+UseNUMA来启用。

  激进优化特性

  在Java1.6中,激进优化(AggressiveOpts)是默认开启的。激进优化是一般有一些下一个版本才会发布的优化选项。但是有可能造成不稳定。前段时间以讹传讹的JDK7的 Bug,就是开启这个选项后测到的。

  逃逸分析

  让一个对象在一个方法内创建后,如果他传递出去,就可以称为方法逃逸;如果传递到别的线程,成为线程逃逸。如果能知道一个对象没有逃逸,就可以把它分配在栈而不是堆上,节约GC的时间。同时可以将这个对象拆散,直接使用其成员变量,有利于利用高速缓存。如果一个对象没有线程逃逸,就可以取消其中一切同步操作,很大的提高性能。

  但是逃逸分析是很有难度的,因为花了cpu去对一个对象去分析,要是他不逃逸,就无法优化,之前的分析血本无归。所以不能使用复杂的算法,同时现在的 JVM 也没有实现栈上分配。所以开启之后,性能也可能下降。

  可以使用-XX:+DoEscapeAnalysis来开启逃逸分析。

  高吞吐量GC配置

  对于高吞吐量,在年轻态可以使用Parallel Scavenge,年老态可以使用Parallel Old垃圾收集器。

  使用-XX:+UseParallelOldGC开启

  可以将-XX:ParallelGCThreads根据CPU的个数进行调整。可以是CPU数的1/2或者5/8

  低延迟GC配置

  对于低延迟的应用,在年轻态可以使用ParNew,年老态可以使用CMS垃圾收集器。

  可以使用-XX:+UseConcMarkSweepGC和-XX:+UseParNewGC打开。

  可以将-XX:ParallelGCThreads 根据CPU的个数进行调整。可以是CPU数的1/2或者5/8

  可以调整-XX:MaxTenuringThreshold(晋升年老代年龄)调高,默认是15。这样可以减少年老代GC的压力

  可以-XX:TargetSurvivorRatio,调整Survivor的占用比率。默认50%。调高可以提供Survivor区的利用率

  可以调整-XX:SurvivorRatio,调整Eden和Survivor的比重。默认是8。这个比重越小,Survivor越大,对象可以在年轻态呆更多时间。

转载于:https://www.cnblogs.com/anyehome/p/8880889.html

多核服务器的JVM优化选项(转载)相关推荐

  1. 认识 java JVM虚拟机选项 Xms Xmx PermSize MaxPermSize 区别

    认识 java JVM虚拟机选项 Xms Xmx PermSize MaxPermSize 区别 2012-08-24 12:15 点击window---->preferences----> ...

  2. Web服务器Nginx多方位优化策略

    Nginx(读音engine x)服务器由于性能优秀稳定.配置简单以及跨平台,被越来越多的公司和个人所采用,现已成为市场份额继Apache之后的第二大Web服务器.各大小网站论坛博客也介绍说明了Ngi ...

  3. JVM优化及面试热点分析

    学习目标 能够描述运行时数据区域 能够说出垃圾回收机制 能够说出JVM的类加载机制 能够说出双亲委托模型 能够使用JVM性能监控工具 能够说出JVM性能调优 JVM优化及面试热点分析 jvm的组成 类 ...

  4. Java JVM虚拟机选项Xms/Xmx/PermSize/MaxPermSize(转)

    通过JVM的这些选项:Xms/Xmx/PermSize/MaxPermSize可以牵扯出很多问题,比如性能调优等. 说明:以下转载没经过实践.转自: Java JVM虚拟机选项Xms/Xmx/Perm ...

  5. Java之JVM 优化经验总结

    为什么80%的码农都做不了架构师?>>>    开始之前 Java 虚拟机有自己完善的硬件架构, 如处理器.堆栈.寄存器等,还具有相应的指令系统.JVM 屏蔽了与具体操作系统平台相关 ...

  6. JVM 优化经验总结

    转载自  JVM 优化经验总结 开始之前 Java 虚拟机有自己完善的硬件架构, 如处理器.堆栈.寄存器等,还具有相应的指令系统.JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生 ...

  7. Tomcat、JVM 优化配置

    为了让Tomcat稳定长期的运行,提高性能,默认的配置肯定是不行的. 从两个方向入手:Tomcat本身配置优化和JVM优化 环境:Tomcat8+JDK1.8+Linux Ubuntu16.04 一. ...

  8. Tomcat调优和JVM优化

    title: Tomcat调优和JVM优化 date: 2018-7-22 19:27:56 tags: [Tomcat,Java,JVM] categories: [JVM] Tomcat本身优化 ...

  9. JVM优化之优化常用参数和工具

    JVM优化之优化常用参数和工具 内容提要 jvm运行参数和参数设置 jvm 内存模型 定位分析死锁和内存溢出 其他工具使用 为什么要优化JVM 1.生产环境需要承载更多的并发要求,对底层的优化能显著提 ...

最新文章

  1. python 脚本撞库国内“某榴”账号
  2. IPC进程间通信 D-Bus(Desktop Bus)快速入门(以libdbus-glib库为例)
  3. boost::replace_if相关的测试程序
  4. 告别加班:一个让你不再重复工作的技能
  5. 静态路由实验配置举例
  6. BZOJ4653: [Noi2016]区间(线段树 双指针)
  7. ELKF(Elasticsearch+Logstash+ Kibana+ Filebeat) 部署
  8. 小D课堂 - 零基础入门SpringBoot2.X到实战_第8节 数据库操作之整合Mybaties和事务讲解_36、SpringBoot整合mybatis之事务处理实战...
  9. Windows Phone 学习 Web搜索组件
  10. 合肥工业大学机器人技术期末_机器人技术基础期末考试复习资料
  11. 数值计算方法第一章—数值计算引论
  12. caxa发生文件读写异常_文件和异常
  13. 【图像识别】人脸识别原理及CNN讲解
  14. 服务器防火墙的作用是什么?如何设置?
  15. 中断上下文中的preempt count
  16. Idea的类注释和方法注释
  17. NE5532DR IC OPAMP GP 2 CIRCUIT 8SOIC
  18. 如何在element-plus配套vue3中使用日期时间选择器默认英文修改为中文
  19. 百度小程序版帝国cms插件
  20. 2019FME博客大赛——基于 FME 求算最佳租房方案

热门文章

  1. 30天敏捷结果(4):放弃一些事情
  2. 大数据量,海量数据 处理方法总结(转)
  3. 关于在SVG中如何实现gif动画的问题?
  4. adb通信协议分析以及实现(二):adb服务进程发现设备
  5. ThinkPHP框架搭建网站
  6. 在VS2010中使用wxWidgets 2.9.3
  7. 诺基亚Lumia 800生产背后的故事——萨罗工厂[多图]
  8. 【转蝈蝈俊.net 】SQL Server 2005 配置发送邮件
  9. JavaScript的9个陷阱及评点
  10. 表单验证自定义二选一