美文网首页
调优案例分析与实战

调优案例分析与实战

作者: 官子寒 | 来源:发表于2020-02-12 17:05 被阅读0次

1 调优案例分析

1.1 高性能硬件上的程序部署策略

在高性能硬件上部署程序的两种策略:

  • 通过64位JDK来使用大内存
  • 使用若干个32位虚拟机建立逻辑集群来利用硬件资源

策略1要考虑的问题:

  1. 使用大内存的前提是有把握应用程序的FUll GC频率控制的足够低,至少低到不会影响用户使用;而控制FULL GC频率的关键是看应用中绝大多数对象能否符合“朝生夕灭”的规律,即大多数对象的生存时间不应该太长
  2. 内存回收导致长时间停顿
  3. 64位JDK性能可能不如32位
  4. 需要保证程序稳定,因为这种程序一旦发生溢出,转储快照会过于庞大而几乎无法分析
  5. 程序在64位JDK消耗的内存比32位要大

策略2要考虑的问题:

  1. 在逻辑集群的环境下,要尽量避免节点竞争全局的资源,比如磁盘竞争,各个节点如果同时访问磁盘,会很容易导致IO异常
  2. 很难最高效率地使用资源池,比如连接池,因为一般是在各个节点建立独立的连接池,这样可能导致一部分节点满了,另一部分没满
  3. 各个节点会受到32位的内存限制
  4. 大量使用本地缓存的应用,在逻辑集群中会造成较大的内存浪费,因为每个逻辑节点都有一份缓存,可以考虑把本地缓存换为集中式缓存

1.2 集群间同步导致的内存溢出

NAKACK文件JBossCache经过NAKACK栈用于保障各个包的有效顺序及重发
当网络不良好的时候,会产生大量NAKACK文件的堆积

java有垃圾回收机制,为什么还会出现内存溢出

1.3 堆外内存导致的溢出错误

NIO操作会用到直接内存

  • Direct Memory: 可通过-XX:MAXDIrectMemorySIze来调整大小,内存不足时抛出OOM
  • 线程堆栈:可通过-Xss来调整大小
  • Socket缓存区:每个Socket连接都有Receiver和Send两个缓存区,分别占大小37KB和25KB,连接多的话这块内存占用也比较可观
  • JNI代码:JNI使用的内存也在堆外
  • 虚拟机和GC

1.4 外部命令导致虚拟机缓慢

例如Runtime.getRuntime().exec()这种调用方式很消耗资源,它需要

  1. 克隆一个和当前虚拟机拥有一样环境变量的进程
  2. 用这个进程去执行命令
  3. 退出这个进程

2. Eclipse运行速度调优

问题一:永久代溢出
问题分析:JDK1.6没有指定-XX:MaxPermSize=256M
解决方案:指定-XX:MaxPermSize=256M

问题二:类加载时间过长
问题分析:字节码验证需要占用大量时间
解决方案:关闭字节码验证,使用参数-Xverify:none

问题三:编译时间过长
问题分析:JDK1.2以后,虚拟机内设了两个运行时编译器,如果方法被调用的次数达到一定程度,就会被判定为热代码,从而交给JIT编译器及时编译为本低代码,这回消耗程序正常运行的时间,即编译时间
解决方案:使用-Xint禁止编译器运作,但这也会让给Eclipse启动时间变长

C1编译器
C2编译器

问题四:老年代内存自动扩张
解决方案:将老年代容量固定下来

问题五:Eclipse显式调用System.gc()
解决方案:使用-XX:+DisableExplicitGC

问题六:选择收集器不当

相关文章

网友评论

      本文标题:调优案例分析与实战

      本文链接:https://www.haomeiwen.com/subject/insuxhtx.html