性能调优专栏
-
tomcat性能优化整理
(1) 如何给tomcat调优
① JVM参数调优 -Xms<size>表示JVM初始化堆的大小,-Xmx<size>表示JVM堆的最大值。一般建议堆的最大值设置为可用内存大小的80%。在cataline.bat中,设置JAVA_OPTS=’-Xms256m-Xmx512m’,表示在初始化内存为256MB,最大使用内存为512MB
② 禁止DNS查询.DNS查询需要占用网络,并且包括可能从很远的服务器或者不起作用的服务器上去获取对应的IP的过程,这样会消耗一定的时间。为了消除DNS查询对性能的影响可以关闭DNS查询,方式是server.xml文件中enableLookups参数值:修改为false
③ 调整线程数
(2) 如何加大tomcat连接数
① 在tomcat配置文件server.xml中的<Connector>配置中,和连接相关的参数有
1) Minprocessor :最小空闲连接线程数,用于提高系统处理性能,默认值为10
2) Maxprocessor:最大线程连接数,即并发处理的最大请求数,默认值为75
3) acceptCount:允许的最大连接数,应大于等于maxprocessor,默认值为100
4) enableLookups:是否反查域名,取值为ture或false。为了提高处理能力,需要设置为false
5) connectionTimeout:网络连接超时,单位:毫秒。设置为0表示永不超时,但是这样设置是由隐患的,通常设置为30000毫秒
6) Web server:允许的最大连接数还受制于操作系统的内核参数设置,通常windows是2000个左右,Linux是1000个左右
(3) Tomcat优化经验
① Tomcat作为web容器,它的处理性能直接关系到用户体验,下面是常见的优化措施
1) 去掉对web.xml的监视,把jsp提前编译成servlet。有富裕内存的情况下,加大tomcat使用JVM的内存
2) 服务器资源:服务器所能提供CPU、内存、硬盘的性能对处理能力有决定性影响
3) 对于高并发情况下会有大量的运算,那么CPU的速度会直接影响到处理速度
4) 内粗在大量数据处理的情况下,将会有较大的内存容量需求,可以用-Xmx-Xms-XX:MaxPermSize等参数对内存不同功能快进行划分
5) 硬盘的主要问题就是读写性能,当大量文件进行读写时,磁盘极容易称为性能瓶颈。做好的办法还是下面将会提到的缓存
6) 利用缓存和压缩:对于静态页面最好能够缓存起来,不必每次都从磁盘进行读取。可以采用Nginx作为缓存服务器,将图片、js、css文件进行缓存,有效减少了后端tomcat的访问
7) 采用集群:单个服务器的性能总是有限的,横向扩展时非常有效的方发,即组建集群
8) 优化tomcat参数
- JVM性能优化
(1) Java类加载过程,java类加载需要经历以下7个阶段
① 加载:完成一下三个事情
1) 通过一个类的全限定名获取该类的二进制流
2) 将该二进制流中的静态存储结构转换为方法去运行时数据结构
3) 在内存中生成该类的Class对象,作为该类的数据访问入口
② 验证:验证的目的是为了确保Class文件的字节流中的信息不会危害到虚拟机,在该阶段主要完成一下四种验证
1) 文件格式验证:验证字节流是否符合Class文件的规范
2) 元数据验证:对字节码描述的信息进行语义分析,如这个类是否有父类,是否集成了不能被继承的类等
3) 字节码验证:是整个验证过程中最复杂的阶段。通过验证数据流和控制流的分析,确定程序语义是否正确,主要针对方法体的验证,如:方法中的类型转换是否正确,跳转指令是否正确等
4) 符号引用验证:这个动作在后面的解析过程中发生,主要是确保解析动作能正确执行
③ 准备:为类的静态变量分配内存并将其初始化为默认值,这些内存都将在方法区中进行分配。
④ 解析:主要完成符号引用到直接引用的转换动作。解析动作并不一定在初始化动作之前完成,也有可能在初始化之后完成
⑤ 初始化:初始化是类加载的最后一步,前面的类加载过程,除了在加载阶段用户应用程序可以通过自定义类加载参与之外,其余动作完全由虚拟机主导和控制。到了初始化阶段,才开始真正执行类中定义的java程序代码
⑥ 使用
⑦ 卸载
(2) java内存分配
① 寄存器,这是我们无法控制的
② 静态域:static定义的静态成员
③ 常量池:编译时被确保并保存在.class文件的final常量值和一些文本修饰的符号引用
④ 非RAM存储:硬盘等永久存储空间
⑤ 堆内存:new 创建的对象和数组,由java虚拟机自动垃圾回收器管理,存取速度慢
⑥ 栈内存:基本类型的变量和对象的引用变量,速度快、可以共享,但是大小与生命周期确定;缺乏灵活性
(3) 垃圾回收的优点和原理。并考虑两种回收机制
① 由于有了垃圾回收机制,java中的对象不再有”作用域”的概念,只有对象的引用才有”作用域”,垃圾回收可以有效的防止内存泄漏,有效的使用可以使用的内存。垃圾回收器通常是作为一个单独的低级别的线程运行,不可预知的情况下对内存堆中已经死亡的或长时间没有使用的对象进行清除和回收,程序员不能实时的调用垃圾回收器对某个对象或所有对象进行垃圾回收
(4) 垃圾回收期的基本原理是什么?垃圾回收器可以马上回收内存吗?有什么办法可以主动通知虚拟机进行垃圾回收吗?
① 对于GC来说,当程序员创建一个对象时,GC就开始监控这个对象的地址、大小以及使用情况。通常,GC采用有向图的方式记录和管理堆中的所有对象。通过这方式确定哪些对象时可达的,哪些对象是不可达的。当GC确定某些对象不可达时,就会进行垃圾回收。程序员可以手动的通过System.gc(),通知GC运行,但是java的语规范并不能保证GC一定运行
(5) 深拷贝和先拷贝:简单来说就是复制、克隆
① 浅拷贝:就是对对象中的数据成员进行简单复制,如果存在动态成员或指针就会报错
② 深拷贝:就是对对象中存在的动态成员和指针重新开辟内存空间
(6) 如果对象的引用被置为null,垃圾收集器是否会立即释放对象占用的内存?
① 不会,在下一个垃圾回收周期中,这个对象是可被回收的
(7) 什么是分布式垃圾回收(DGC)?他是如何工作的?
① RMI使用DGC来做自动垃圾回收。因为RMI包含了跨虚拟机的远程对象的引用,垃圾就收是很困难的。DGC使用引用计数器算法来给远程对象提供自动内存管理
(8) 串行(Serial)收集器和吞吐量(throughput)收集器的区别是什么?
① 吞吐量收集器采用并行版本的新生代垃圾收集器,它用于中等规模和大规模数据的应用程序,而串行收集器对大多数的小应用就足够了
(9) 简述java内存分配与回收策略以及Minor GC和Major GC
① 对象优先在堆的Eden区分配
② 大对象直接进入老年代
③ 长期存活的对象将直接进入老年代
④ 当Eden区没有足够的空间进行分配时,虚拟机会执行一次Minor GC.MinorGC通常发生在新生代的Eden区,在这个区的对象生存期短,往往发生GC的频率较高,回收速度比较快;Full GC/Major GC发生在老年代,一般情况下,触发老年代GC的时候不会触发Minor GC,但是通过配置可以在Full GC之前进行一次Minor GC,这样可以加快老年代的回收速度
(10) 什么时类加载器?类加载器都有哪些?
① 实现通过类的权限定名获取该类的二进制字节流的代码块叫做类加载器
② 主要有以下四种类加载器
1) 启动类加载器(BootStrapClassLoader)用来加载java核心类库,无法被java程序直接引用
2) 扩展类加载器(extensions class loader):用来加载java的扩展库。Java虚拟机的实现会提供一个扩展库目录。该类加载器再次目录里面查找并加载java类
3) 系统类加载器(system class loader)它更具java应用的类路径来加载java类。一般来说,java应用的类都是由它来完成加载的。可以通过ClassLoader.getSystemClassLoader()来获取
4) 用户自定义类加载器:通过继承lava.lang.ClassLoader类的方式实现
(11) 类加载器双亲委派模型机制?
① 当一个类收到类加载请求时,不会自己先去加载这个类,而是将其委派给父类,由父类去加载,如果此时父类不能加载,反馈给子类,由子类完成类的加载