先说下问题是怎么来的吧。html
项目背景:如今正在作的是一个爬虫项目,爬虫主要爬取各大电商的商品数据,而后清洗进入索引库,为客户提供搜索导购服务(说白了就是导购服务)。爬取这些数据的要求:实时性、准确性。重点是实时性,须要爬虫保证天天至少爬取一遍这些数据,对商品库进行更新。那么问题就来了,爬虫确定是多线程的,并且要求执行效率要特别高,就是要快。从第一个版本的纯手工方式,到第二个版本的多线程调度和任务分配(主要是方便监控)。linux
问题表现:项目在本机跑起来100个线程毫无压力,并且cpu利用率也特别好。因此就直接部署到了测试环境的服务器上,跑了一个晚上次日早上依赖发现内存溢出了,并且这个溢出之前没怎么见过,通常你们场景的内存溢出都是Java heap space或PermGen space ,而我此次遇到的是GC overhead limit exceeded,相信你们也不多遇到。(若是你们遇到前面两种请参考java内存溢出的三种状况和解决方案)windows
解决思路:tomcat
一、首先确定是百度咯,百度不行翻出去google咯,找一些资料看了下,官方也有说明。问题根本缘由是jvm gc行为中超过98%以上的时间去释放小于2%的堆空间时会报这个错误。服务器
二、为何本机能够,到了测试服务器上不行了,而后一看服务器内存竟然4G,运维的兄弟太坑了,给分那么点,我笔记本都是8g呢。后来先要求加内存到8G,可是仍是没解决根本问题。多线程
三、查看了下内存使用状况,仍是溢出了,致使新的线程没法建立,测试服务器使用线程池开了300个线程,不至于啊。因此只有修改tomcat的默认配置了,其实就加了2个参数,(linux就修改catalina.sh,windows固然是修改catalina.bat,加在文件的开头)运维
HEAP_SIZE="6000M"
NEW_SIZE="4200M"jvm
另外还多加了两个参数 ,提供jconsole链接的,方便监控jvm,若是再出问题就得靠这玩意儿了。ide
SERVER_IP="192.168.16.12"
SERVER_PORT="1909"测试
下图是链接jconsole后监控的界面,你们会发现GC频率并不高,可是很高效