之前接手一个别人刚写好的项目,丢到服务器上跑了没几天,服务器上别的服务都不能使用了。查看阿里云控制台,发现内存爆满了,只能先把这个服务先下,保证别的服务正常使用,还好是在测试阶段,还没正式上线。
对于内存泄露,一开始以为是Java I/O操作没有关闭,导致Java JVM内存泄露。但是发现项目中的I/O操作都已经把做了close操作。最后使用 jconsole 来监控本地内存的变化,发现是不断的创建线程,导致内存的不足,本地长时间跑项目出现下面的错误,这个和通过jconsole监控内存得出的结果差不多。
1 | java.lang.OutOfMemoryError: unable to create new native thread |
于是就到项目中看了下,项目中对于线程的创建,终于知道什么问题了。项目中线程的创建没有通过线程池,而是直接new Thread
和通过 ScheduledExecutorService
定时创建线程,导致线程耗尽内存。
在阿里的Java开发手册中,就指出项目中的对于线程的创建,必须通过线程池,不能私自创建线程。关于线程池可以看这篇博客。