关于java性能的小笔记

简介:   一、大规模高并发访问的性能分析: 1.应用服务器中JVM的优化: 在安装JDK后,有两个JVM虚拟机,分别是server jvm和 client jvm。其中server jvm比client jvm进行了更多的优化,所以在开发和测试Web应用系统时,应用指定服务器的jvm虚拟机为server jvm。        启动client jvm 和server jvm的方式:
 

一、大规模高并发访问的性能分析:

1.应用服务器中JVM的优化:

在安装JDK后,有两个JVM虚拟机,分别是server jvm和 client jvm。其中server jvm比client jvm进行了更多的优化,所以在开发和测试Web应用系统时,应用指定服务器的jvm虚拟机为server jvm。

       启动client jvm 和server jvm的方式:

       Java –client yourclass

       Java –server yourclass

       其中client jvm是默认的启动方式。在tomcat服务器中,通常会有如下两种设置jvm虚拟机的方式:

●   %java_home%/jre/bin/client/jvm.dll

●   %java_home%/jre/bin/server/jvm.dll

Jvm动态库有client和server两个版本,分别针对桌面应用和服务器应用做了相应优化,其中client版本加载速度较快,server版本加载速度较慢但运行起来较快。一般在tomcat服务器中,应使用server版本。

 

2.  JVM虚拟机中对字节码优化的策略:

Server jvm和client jvm对字节码优化的策略不同:

●Client主要优化对用户交互的相应速度。

●Server主要优化后台运行的代码。

使用server模式可以提高性能,启动比client模式慢,长期运行则比client模式快。当该参数不指定时,虚拟机启动检测主机是否为服务器,如果是,则以server模式启动,否则以client模式启动。J2SE 5.0检测的根据是至少2个CPU和最低2GB内存。

3.  堆大小设置:

JVM中最大堆大小有三方面限制:相关操作系统的数据模型(32bit还是64bit)限制;系统的可用物理内存限制。在32位系统下,一般限制在1.5-2G,在64位系统下,操作系统对内存无限制。

常用的典型设置如下:

●Java –Xmx3550m –Xms3550m –Xmn2g –Xss128k

●-Xmx3550m: 设置JVM最大可用内存为3550。

 

-Xms3550m:设置JVM初始化内存为3550M。此值可以设置于-Xmx相同,以避免每次垃圾回收完成后JVM重新分配内存。

-Xmn2g:设置年轻代大小为2G。整个堆大小=年轻代大小+年老代大小+持久代大小。持久代大小一般固定大小为64M,所以增大年轻代后,将会减小年老代大小。此值对系统性能影响较大,Sun 官方推荐配置为整个堆的3/8。基于对对象生命周期分析后得出的垃圾回收算法,把对象分为年轻代,年老代,持久代,对不同的生命周期的对象使用不同的算法(上述方式中的一个)进行回收。现在的垃圾回收器(从J2SE 1.2开始)都是使用此算法的。

-Xss128k:设置每个线程的堆栈大小。从JDK5.0每个堆线程大小为1M,以前每个线程堆大小为256K。可根据具体应用调整线程所需内存大小。在相同物理内存下,减小这个值能生成更多的线程。但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,通常值在3000~5000左右。

4.回收器选择:

       在JVM中给三种回收器的选择:串行收集器、并行收集器、并发收集器,但是串行收集器只适用于小数据量的情况,所以这里的选择主要针对并行收集器和并发收集器。默认情况下,在JDK5.0以前都是使用串行收集器,如果想使用其他收集器需要在启动时加入相应参数,从JDK5.0以后,JVM会根据当前系统配置进行判断。

       并行收集器主要以达到一定的吞吐量为目标,适用于科学技术和后台处理等,典型配置如下:

java-Xmx2800m-Xms800m-Xmn2g-Xss128k-XX:+UserParallelGC-XX:ParallelGCThreads=20-XX:+UserParallelOldGC

    ●-XX:+UserParallelGC:选择垃圾收集器为并行收集器。此配置仅对年轻代有效。即上述配置下,年轻代使用并发收集,而年老代仍旧使用串行收集。

       ●-XX:ParallelGCThreads=20:配置并行收集器的线程数,即同时多少个线程一起进行垃圾回收。此值最好配置与处理器数目相等。

       ●-XX:+UserParallelOldGC:配置年老代垃圾收集方式为并行收集,JDK6.0支持对年老代并行收集。

       并发收集器主要是保证系统的响应时间,减少垃圾收集时的停顿时间。适用于应用服务器、电信领域等。典型配置如下:

Java-Xmx3550m-Xms3550-Xmn2g-Xss128k-XX:ParallelGCThreads=20-XX:+UserConcMarkSweepGC-XX:+UserParNewGC

       ●-XX:+UseConcMarkSweepGC:设置年老代为并发收集。

       ●-XX:+UseParNewGC:设置年轻代为并行收集。可与CMS收集同时使用。从JDK5.0开始,JVM会根据系统配置自行设置,所以无需再设置此值。

5.年轻代大小选择:
       响应时间优先的应用:年轻代尽可能设大,直到接近系统的最低响应时间限制(根据实际情况选择)。在此种情况下,年轻代收集发生的频率也是最小的。同时减少到达年老代对象。

吞吐量优先的应用:年期代尽可能的设置大,可能达到Gbit的程度。因为对响应时间没有要求,垃圾收集可以并行进行,一般适合8CPU以上的应用。

6.年老代大小选择:

       响应时间优先的应用:年老代使用并发收集器,所以其大小需要小心设置,一般要考虑并发会话率和会话持续时间等一些参数。如果堆设置小了,可能会造成内存碎片、高回收频率以及应用暂停而使用传统的标记清除方式:如果堆大了,则需要较长的收集时间。最优化的方案,一般需要参考以下数据获得:

●    并发垃圾收集信息。

●    持久代并发收集次数

●    传统GC信息

●    花在年轻代和年老代回收上的时间比例

●    减少年轻代和年老代花费的时间,一般会提高应用的效率

吞吐量优先的应用:一般吞吐量优先的应用都有一个很大的年轻代和一个较小的年老代。原因是:这样可以尽可能回收掉大部分短期对象,减少中期的对象。

 

7.较小堆引起的碎片分析:

       因为年老代的并发收集器使用标记、清除算法,所以不会对堆进行压缩。当收集器回收时,它会把相邻的空间进行合并,这样可以分配给较大的对象。但是当堆空间较小时,运行一段时间以后,就会出现“碎片”,如果并发收集找不到足够的空间,那么并发收集器将会停止,然后使用传统的标记、清除方式进行回收。如果出现“碎片”,可能需要进行如下配置:

       ●-XX:+UserCMSCompactAtFullCollection:使用并发收集器时,开启对年老代的压缩。

       ●-XX:CMSFullGCsBeforeCompaction=0:上面配置开启的情况下,这里设置多少次Full GC后,对年老代进行压缩。

8.在实际编程中对内存的优化:

       应用java开发的系统给人的印象是占内存,其实从理论上来讲,java开发的系统并不比其他语言开发的系统更占用内存,这就需要子啊编程时注意优化内存。

       ●不要使用new Boolean().

       ●不要使用new Integer()

    ●用StringBuffer代替字符串相加

    ●过滥使用哈希表

    ●避免过深的类层次结构和过深的方法调用。因为这两者都是非常占用内存的(特别是方法调用更是堆栈空间的消耗大户)

    ●变量只用在用到它的时候才定义和实例化

    ●尽量避免使用static变量,类内私有常量可以有final来代替

    ●尽早释放无用对象的引用

    ●尽量少用finalize函数。它会增加GC的工作量

    ●尽量避免在类的默认构造器中创建和初始化大量的对象,防止在调用其构造器时造成不必要的内存资源浪费

    ●尽量避免强制显示申请数组空间

    ●尽量做远程方法调用类应用开发时使用瞬间值变量,除非远程调用端需要获取该瞬间值变量的值。

    ●尽量在合适的场景下使用对象池技术以提高系统性能

9.集群与负载均衡

    在单一的服务器上执行某些应用程序会出现一些重大问题。当网站成功建成并开始接受大量请求时,单一服务器终究无法满足需要处理的负荷量,所以就显得有点力不从心了。另外一个常见的问题是会产生单点故障,如果该服务器坏掉,那么网站就立刻无法运行了。不论是因为要有较佳的扩充性还是要有容错能力。都希望在一台以上的服务器计算机上执行该应用程序,这就需要用到集群技术。

    集群(luster)一组独立的计算机系统构成一个松耦合的多处理系统,他们之间通过网络实现进程间的通信。应用程序可以通过网络共享内存进行消息传送,实现分布式计算机。

    集群系统主要解决下面几个问题:

●    高可靠性(HA):利用集群管理软件,当主服务器故障时,备份服务器能够自动接管主服务器的工作,并及时切换过去,以实现对用户的不间断服务。

●    高性能计算(HP):即充分利用集群中的每一台计算机的资源,实现复杂运算的并行处理,通常用于科学计算领域,如基因分析,化学分析。

●    负载平衡:即把负载压力根据某种算法合理分配到集群中每一台计算机上,以减轻服务器压力,降低对主服务器的硬件和软件需求。

●    负载均衡(oad Balance):集群就是一组连在一起的计算机,从外部看它是一个系统,各节点可以是不同的操作系统或不同硬件构成的计算机。如一个提供Web服务的集群,从外界来看是一个大的WEB服务器。不过集群的节点也可以单独提供服务。在现有网络结构之上,负载均衡提供了一种廉价有效的方法扩展服务器带宽和增加吞吐量,加强网络数据处理能力,提高网络的灵活性和可用性。

目前比较常用的负载均衡技术主要如下:

1.基于DNS的负载均衡

a)        通过DNS服务中的随机名字来实现负载均衡,在DNS服务器中,可以为多个不同的地址配置同一个名字,而最终查询这个名字的客户机讲在解析这个名字时得到其中一个地址,因此,对于同一个名字,不同的客户机会得到不同的地址,他们也就访问不同地址上的WEB应用服务器,从而达到负载均衡的目的。

反向代理负载均衡
相关实践学习
部署高可用架构
本场景主要介绍如何使用云服务器ECS、负载均衡SLB、云数据库RDS和数据传输服务产品来部署多可用区高可用架构。
负载均衡入门与产品使用指南
负载均衡(Server Load Balancer)是对多台云服务器进行流量分发的负载均衡服务,可以通过流量分发扩展应用系统对外的服务能力,通过消除单点故障提升应用系统的可用性。 本课程主要介绍负载均衡的相关技术以及阿里云负载均衡产品的使用方法。
目录
相关文章
|
23天前
|
设计模式 Java
Java基础—笔记—多态、final、抽象类、接口篇
该文介绍了编程中的多态、final和抽象类、接口相关概念。多态允许子类重写父类方法,通过父类引用调用子类方法,实现解耦和提高代码灵活性,但也可能导致无法使用子类特有功能,需通过强制类型转换解决。final用于修饰不可变的类、方法或变量,防止继承、重写和多次赋值。抽象类是一种包含抽象方法的类,用于强制子类重写特定方法,实现多态,适用于模板方法设计模式,解决代码重复问题。
17 0
|
23天前
|
Java
Java基础—笔记—static篇
`static`关键字用于声明静态变量和方法,在类加载时初始化,只有一份共享内存。静态变量可通过类名或对象访问,但推荐使用类名。静态方法无`this`,不能访问实例成员,常用于工具类。静态代码块在类加载时执行一次,用于初始化静态成员。
10 0
|
23天前
|
Java API 索引
Java基础—笔记—String篇
本文介绍了Java中的`String`类、包的管理和API文档的使用。包用于分类管理Java程序,同包下类无需导包,不同包需导入。使用API时,可按类名搜索、查看包、介绍、构造器和方法。方法命名能暗示其功能,注意参数和返回值。`String`创建有两种方式:双引号创建(常量池,共享)和构造器`new`(每次新建对象)。此外,列举了`String`的常用方法,如`length()`、`charAt()`、`equals()`、`substring()`等。
15 0
|
28天前
|
监控 Java API
提升 Java 后台性能的十大方法
【4月更文挑战第5天】本文介绍了提升 Java 后台性能的十大方法,包括 JVM 参数调整、代码优化、并发编程、数据库性能优化、I/O 优化、微服务架构、API 设计、负载均衡、容器化和编排以及性能监控。通过这些方法,可以从代码到系统层面全面提升 Java 应用的效率和响应性。注意早期设计对性能的影响,持续优化是关键。
|
3天前
|
算法 安全 Java
性能工具之 JMeter 自定义 Java Sampler 支持国密 SM2 算法
【4月更文挑战第28天】性能工具之 JMeter 自定义 Java Sampler 支持国密 SM2 算法
16 1
性能工具之 JMeter 自定义 Java Sampler 支持国密 SM2 算法
|
6天前
|
存储 安全 算法
【JAVA】HashMap扩容性能影响及优化策略
【JAVA】HashMap扩容性能影响及优化策略
|
1天前
|
存储 缓存 前端开发
Java串口通信技术探究3:RXTX库线程 优化系统性能的SerialPortEventListener类
Java串口通信技术探究3:RXTX库线程 优化系统性能的SerialPortEventListener类
11 3
|
2天前
|
Java 编译器 Android开发
构建高效Android应用:探究Kotlin与Java的性能差异
【5月更文挑战第1天】 在移动开发的世界中,性能优化始终是开发者关注的焦点。随着Kotlin的兴起,许多团队和开发者面临着一个选择:是坚持传统的Java语言,还是转向现代化、更加简洁的Kotlin?本文通过深入分析和对比Kotlin与Java在Android应用开发中的性能表现,揭示两者在编译效率、运行速度和内存消耗等方面的差异。我们将探讨如何根据项目需求和团队熟悉度,选择最适合的语言,以确保应用的高性能和流畅体验。
|
3天前
|
Java 编译器 Android开发
构建高效Android应用:探究Kotlin与Java的性能差异
【4月更文挑战第30天】在Android开发领域,Kotlin作为一种现代化的编程语言,因其简洁性和功能性受到了开发者的广泛欢迎。尽管与传统的Java相比,Kotlin提供了诸多便利,但关于其性能表现的讨论始终未息。本文将深入分析Kotlin和Java在Android平台上的性能差异,通过实际测试数据揭示两种语言在编译效率、运行速度以及内存占用方面的具体表现,并探讨如何利用Kotlin的优势来提升Android应用的整体性能。
|
6天前
|
Java 大数据 Go
Go vs Java:在大数据处理领域的性能对比
Go与Java在大数据处理中各有特点。Go启动快,内存占用少,静态类型及并发模型(goroutine和channel)使其在并发性能上有优势。Java虽然启动慢,JVM内存占用高,但拥有丰富的生态系统和并发工具。代码示例展示了Go的goroutine和Java的线程池处理大数据的场景。在性能上,Go可能更优,但Java的跨平台性和生态广度使其仍被广泛应用。