windows服务器中查看java占用CPU过高的方法(记自己实践及代码中的一些坑)

本文引用自:windows 排查javaWeb程序占用CPU过高问题(可追踪到问题代码所在行)_51CTO博客_windows java cpu过高排查

https://blog.51cto.com/u_15964717/6059215

坑1:cmd中运行【 jstack 16992 > d:/a.txt 】时提示:

'jstack' 不是内部或外部命令,也不是可运行的程序
或批处理文件。

原因是环境变量里没有JDK,cmd没找到jdk下的jstack这个命令

解决方法:用cd命令切换到jdk目录的bin中再执行这个命令。

坑2:cmd中运行【jstack 16992 > d:/a.txt】时提示:

16992: 拒绝访问。

我这里的原因是登录windows的账号没有权限。

解决方法:切换为administrator登录windows即可。

坑3:导致CPU占用100%的罪魁祸首 —— 最大的坑:

起因是  为了防止xss攻击,设置了过滤器,将提交的所有请求参数的值中的每个字符过滤一遍,一旦出现【  "   '    <    >  】这四个中的任意一个,则转义为实体字符。

原先的写法是:

		static String escape(String str) {
			if (str == null) {
				return null;
			} else {
				String text = "";
				char c;
				// 转义特殊字符:" 34 ' 39 < 60 > 62
				for (int i = 0; i < str.length(); i++) {
					c = str.charAt(i);
					if (c == 34 || c == 39 || c == 60 || c == 62) {
						text = text + "&#" + (int) c + ";";
					} else {
						text = text + c;
					}
				}
				return text;
			}
		}

这个逻辑看起来似乎没什么问题,并且也一直这样用了两年多。但没有问题的前提是请求字段的值不算太长。直到最近,业务新需求是【用base64字符串上传图片】。这里直接就引发问题了。base64字段的值非常长(照片大小500KB左右),每一次请求的长度都达到几百万,导致这个for循环半分钟才能完成。但是,在半分钟之内,此次循环还没结束,下一次请求又来了。频繁请求之下,CPU当然吃不消了,所以CPU占到了100%。

网上说CPU占到100%多数情况是出现了死循环,所以我写代码一般都会避免死循环。这个虽然不是死循环,但它产生了和死循环差不多的效果。

优化后的代码:

	private static String escape(String str) {
		if(str == null) {return null;}
		str = str.replace("'", "&#39;");
		str = str.replace("\"", "&#34;");
		str = str.replace("<", "&lt;");
		str = str.replace(">", "&gt;");
		return str;
	}

这个问题耽误一天时间是小事,程序一直崩溃耽误客户使用是关键。

谨以此作个记录,给自己及各位网友的提醒:

写代码时要时刻注意死循环,固然很关键,但同样要注意是否有这种超大循环(百万次循环)的情况出现。尤其是在循环嵌套循环的时候,多层循环嵌套更要尤为注意。

另附:

在某些情况下,为了实现某种功能,部分代码必须反复执行不能停止,这时一般都会采用死循环的方式。死循环并非不能用,但一定要控制好。如果功能要求必须无限重复,循环次数无限大,那么这时就一定要控制好循环速率。哪怕只是最简单粗暴的方式:【Thread.sleep(毫秒数);】,也别让速度失控(一秒循环十万次)。否则一旦把CPU累趴下 干不动活了,那时程序恐怕也已经走到崩溃的边缘奄奄一息了。

以上仅为个人观点,若有谬误欢迎指正。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值