写了一个处理数据的程序(读取文件数据,插入/更新数据库等),采用多线程(ThreadPoolExecutor),设置线程数:默认3个,最多5个(加主线程最多6个),在服务器A上起单独的jvm跑,没问题;
后来放在服务器B上(性能更好一些),发现在一个批量保存数据库的地方出现了OutOfMemory,感觉是不是线程数多了,就少一点,试到最后,发现只能用一个线程(即默认一个,最多2个),这样才能跑过去,这是因为机器性能好了,多线程在执行保存太快了导致的吗?机器内存啥的都是100G+,cpu也是很牛的,怎么会内存溢出?或者是启动的jvm给的内存不够?
请大神们个分析下,谢谢。
------解决方案--------------------
算你一条数据200个字段,每个字段8个字节,外加一个10000字节的文本,5000条也只有(200 * 8 + 10000) * 5000 = 58MB,3个线程撑死不到200MB内存。查看你的JVM启动内存吧
------解决方案--------------------
应该是你查询数据库,得到的数据量超过你启动内存大小了。tomcat可以在catalina.sh中修改启动内存大小(默认好像是80M),其它容器的配置就不清楚了。
------解决方案--------------------
没设置jvm的内存吧
------解决方案--------------------
机器性能好导致内存溢出?开什么玩笑,啥关系没有.
你机器性能不好也不一定会溢出.
内存溢出就查一下jvm分配的内存是不是小了.另外跟踪一下单位时间插入数据库的数据量.
------解决方案--------------------
检查代码漏洞;调大JVM的-Xmx和Xms,让JVM有更多的可用内存空间。
------解决方案--------------------
读取的数据大小超过了jvm内存限制,跟机器什么关系。
------解决方案--------------------
内存不足有两种可能, jvm内存不足(此时可以尝试用楼上方法),本机内存不足(考虑是否是文件流操作有问题)
------解决方案--------------------
OutOfMemoryError 产生的原因是因为你在内存中加载了大量的数据,估计是你把文件全部读到了一个类似于 List 或者其他什么的数据结构中了,如果文件行数过大,最终只有这样一个结果!
你得读取一些数据操作完成后再去读取第二批数据,这样可以把内存占用控制在一个合理的范围之内,而且几乎不可能会出现 OutOfMemoryError 的错误!
这么大的内存对于这样的程序而言就是大材小用,应该从应用程序本身进行优化,而不是单纯地依赖于增加服务器的硬件配置。
------解决方案--------------------
问题的关键是:楼主的程序,没有控制内存的使用。
解决方案,
一般会设置JVM的最大内存占用值,但是,也会存在内存溢出的风险。
最好是能够优化程序代码,比如,重复使用缓冲区,数组等,尽量减少各种对象的创建操作。
还有,集合对象,使用完毕后,要调用clear方法等。