项目中有个时间戳数据需要定时去取;时间戳保存在远程文本文件中,不同城市的时间戳文本地址不一样。
开发时定时器使用Timer来调度;不通城市的时间戳通过不同线程去取得并更新。
开始项目运行时日志会经常报告JVM内存溢出,开始以为是开的线程过多,因为每个时间段会新建几个线程(开始没有考虑线程池)。
改动使用线程池后过一段时间,还是会出现JVM内存溢出,用Jprofiler查看JVM使用情况,发现JVM会阶梯状升高。
改用线程池后发现这个问题还是会出现,而且情况跟之前差不多。
以为是Timer的问题,改用ScheduledThreadPoolExecutor来操作,发现问题还是一样。
一直纠结这个问题,也许是经验问题。
后来查看URL类的API发现URL对象中openConnection()方法会新建一个到远程目标的连接。查看自己的代码发现自己的每个线程都会新建一个URL对象,并开启一个openConnection(),这样的话我每30秒开启N个线程(使用了线程池)就会新建N个连接操作。发现这个问题后改用:
1.ScheduledThreadPoolExecutor定时启动线程池(2个)
2.每个线程预建一个openConnection();以后线程启动都使用openConnection()得到的同一对象。
改过之后用Jprofiler查看JVM使用情况,发现JVM使用情况稳定。
原来是URL.openConnection()惹的祸。
到底还是经验问题。