一、JVM调优
那么JVM正确的调优方式是啥?我个人推荐四步走:
- 记录好日志;
- 对程序做好性能监控;
- 根据日志和性能监控数据修改程序;
- 使用专业工具通过不同的JVM参数进行压测并获得最佳配置。
例子:
1. 一次是某公司的超大型Java程序,导致PermGen OutOfMemoryError,那是JDK 1.6平台,原因很简单,编写的Java类数量太多了,撑爆了默认的128M的PermGen(永久代) 。
解决方法也很简单,改成更大的512M(新版JVM没有PermGen限制了)。但是根本问题不是出在JVM,而是代码太垃圾,Java类的数量超多造成的。
备注:
1.PermGen空间是为长期对象保留的-大多数对象是ClassLoader加载的Class对象。除非在非常特殊的情况下(特别是当加载这些类的ClassLoader超出范围时),否则不会对PermGen进行垃圾回收。
2.当栈调用深度大于JVM所允许的范围,会抛出*Error的错误,
3.当堆申请不到空间时,会抛出 OutOfMemoryError
4.java.lang.OutOfMemoryError: PermGen space "这个异常。这里的 “PermGen space”其实指的就是方法区由于方法区主要存储类的相关信息,
所以对于动态生成类的情况比较容易出现永久代的内存溢出最典型的场景就是,在 jsp 页面比较多的情况,容易出现永久代内存溢出。
5.在 JDK 1.8 中, HotSpot 已经没有 “PermGen space”这个区间了,取而代之是一个叫做 Metaspace(元空间)
2.另一次是因为TPS超高引起内存不足崩溃,但实际上内存有32G非常大,分配给JVM有30G,不可能用完。现实情况是EC2直接被干掉连日志都看不到了。如果手动把TPS降下来(每次sleep 1ms),就能以一定概率成功启动。后咨询AWS技术支持发现,原来是Kafka这货为了提高速度,用了大量的堆外内存结果在高TPS下爆了。解决方法也很简单,把JVM内存限制在系统内存的一半,给操作系统留出足够的内存。这次根本问题是代码性能太高但错误地设定了XMS和XMX造成的。
备注:
1.TPS( Throughput) 吞吐量
2.Kafka是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者在网站中的所有动作流数据。
3.Xmx用来设置你的应用程序(不是JVM)能够使用的最大内存数
4.Xms用来设置程序初始化的时候内存栈的大小
3.erp系统,单体应用,拖拽式研发,接手时,系统每日卡顿多次,重启耗时30分钟以上。。。。
目前优化结果重启2-5分钟,系统不再卡顿,调整的内容包括更换服务器,从websphere改为tomcat,更改启动参数,更换垃圾回收器,
更改新生代大小,按照官方推荐比例分配,后不断调整最大内存、新生代内存、线程大小、eden区s区的ratio大小,更改fgc指标,更改gc时间占比等等
当然以上的实现思路跟老师的是一样的,日志(异常日志)、监控(调用链路、耗时接口、耗时sql)、jvm内存镜像分析、做出优化方案
备注:
1.WebSphere 是 IBM 的软件平台。它包含了编写、运行和监视全天候的工业强度的随需应变 Web 应用程序和跨平台、
跨产品解决方案所需要的整个中间件基础设施,如服务器、服务和工具。
2.Tomcat 服务器是一个免费的开放源代码的Web 应用服务器,属于轻量级应用服务器,
在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试JSP 程序的首选。
扩展链接:
1. Java8内存模型—永久代和元空间 https://www.cnblogs.com/paddix/p/5309550.html
2.文章来源 https://www.liaoxuefeng.com/article/1336345083510818