关于java:JVM知识总结6JVM性能调优

35次阅读

共计 1395 个字符,预计需要花费 4 分钟才能阅读完成。

在高性能硬件上部署程序,目前有两周形式:

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

应用 64 位 JDK 治理内存

堆内存变大后,尽管垃圾回收的频率缩小了,但每次垃圾回收的工夫变长了。如果堆内存为 14G,那么每次 Full GC 将长达数十秒。如果 Full GC 频繁产生,那么对于一个网站是无法忍受的。
对于用户交互性强、对进展工夫敏感的零碎,能够给 Java 虚拟机调配超大堆的前提是有把握把应用程序的 Full GC 频率管制的足够低,至多要低到不印象用户应用。
可能面临的问题:

  • 内存回收导致长时间的进展
  • 现阶段,64 位 JDK 的性能广泛比 32 位 JDK 低
  • 须要保障程序足够稳固,因为这种利用要是产生堆溢出简直就无奈产生堆转储快照(因为要生产超过 10GB 的 dump 文件),哪怕生产了快照也无奈剖析。
  • 雷同程序在 64 位 JDK 耗费内存个别比 32 位 JDK 大,这是因为指针收缩,以及数据类型对齐补白等因素导致的。

应用 32 位 JVM 建设逻辑集群

在一台物理机上启动多个应用服务器过程,每个服务器过程调配不同端口,而后再前端搭建一个负载均衡器,以反向代理的形式来调配拜访申请。
思考在一台物理机器上建设逻辑集群的目标仅仅是为了尽可能的利用硬件资源,并不需要关怀状态保留、热转移之类的高可用性能需要,也不须要保障每个虚拟机过程有相对的负载平衡,因而应用无 Session 复制的亲合式集群是一个不错的抉择,也不须要保障每一个虚拟机过程有相对的负载平衡,因而应用无 Session 复制的亲合式集群是一个不错的抉择。咱们仅仅须要保障集群具备亲合性,也就是均衡器按肯定的规定算法(个别依据 SessionID 调配)将一个固定的用户申请永远调配到固定的一个集群节点解决即可。
肯能遇到的问题:

  • 尽量避免节点竞争部分资源,如磁盘竞争,各节点如果同时拜访某个磁盘文件的话,很可能导致 IO 异样
  • 很难高效的利用资源池,如连接池,个别都是在节点简历本人独立的连接池,这样有可能导致一些节点池满了而另外一些节点仍有较多空余;
  • 各节点受到 32 位的内存限度
  • 大量应用本地缓存的利用,在逻辑集群中会造成较大的内存节约,因为每一个逻辑节点都有一份缓存,这时候能够思考把本地缓存改成集中式缓存。

调优案例剖析与实际

场景形容

一个小型零碎,应用 32 位 JDK,4G 内存,测试期间发现服务端不定时的抛出内存溢出异样。退出 -XX:+HeapDumpOnOutOfMemoryError(增加这个参数后,堆内存溢出就会输入异样日志),但再次发生溢出时,没有相干日志生成。

剖析

在 32 位 JDK 上,1.6G 调配给堆,还有一部分调配给 JVM 的其余内存,间接内存最大也只能在残余的 0.4G 空间中分出一部分,如果应用了 NIO,JVM 会在 JVM 内存之外分配内存空间,那么就要小心“间接内存”有余时产生内存溢出异样了。

间接内存的回收过程

间接内存尽管不是 JVM 内存空间,但它的垃圾回收也由 JVM 负责。
垃圾收集进行时,虚拟机尽管会对间接内存进行回收,然而间接内存却不能像新生代、老年代那样,发现空间有余了就告诉垃圾收集器进行垃圾回收,它只能等老年代满了后 Full GC,而后“顺便”帮它清理掉内存的废除对象。否则只能始终等到抛出内存溢出异样时,先 catch 掉,再在 catch 块里调用 System.gc()。要是虚拟机还是不听,那就只能眼睁睁看着堆中还有许多闲暇内存,本人却不得不抛出内存溢出异样了。

正文完
 0