我面临java.lang.OutOfMemoryError:无法创建新的本机线程
这些错误以一定的频率出现在两个堆栈中:
首先
java.lang.OutOfMemoryError: unable to create new native thread
at java.lang.Thread.start0(Native Method)
at java.lang.Thread.start(Thread.java:714)
at org.springframework.core.task.SimpleAsyncTaskExecutor.doExecute(SimpleAsyncTaskExecutor.java:213)
at org.springframework.core.task.SimpleAsyncTaskExecutor.execute(SimpleAsyncTaskExecutor.java:171)
at org.springframework.core.task.SimpleAsyncTaskExecutor.submit(SimpleAsyncTaskExecutor.java:185)
at org.springframework.aop.interceptor.AsyncExecutionAspectSupport.doSubmit(AsyncExecutionAspectSupport.java:189)
at org.springframework.aop.interceptor.AsyncExecutionInterceptor.invoke(AsyncExecutionInterceptor.java:123)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:653)
第二
java.lang.OutOfMemoryError: unable to create new native thread
at java.lang.Thread.start0(Native Method)
at java.lang.Thread.start(Thread.java:714)
at java.util.Timer.<init>(Timer.java:160)
at java.util.Timer.<init>(Timer.java:132)
at org.cfg4j.source.reload.strategy.PeriodicalReloadStrategy.<init>(PeriodicalReloadStrategy.java:58)
线程数约为9287个线程:
jstack <pid> | grep "java.lang.Thread.State" | wc -l
9287
98%的线程都在
下面的time_waiting中jstack <pid> | grep "at java.util.TimerThread.mainLoop" | wc -l
9114
"Timer-5962" daemon prio=10 tid=0x00007f4c10769000 nid=0x1a6a1 in Object.wait() [0x00007f4bc62ae000]
java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at java.util.TimerThread.mainLoop(Timer.java:552)
- locked <0x00000006d0297f28> (a java.util.TaskQueue)
at java.util.TimerThread.run(Timer.java:505)
因为我有10,000个线程* 256k + 4 GB的堆,所以我至少有大约6.5 GB的内存消耗。有了4个节点,我达到了服务器的RAM内存的大小限制。所以我认为这是OutOfMemory的原因。
注意:服务器没有线程限制
为什么我有这么多线程与timmed_waiting在java.util.TimerThread.run堆栈?是我的应用程序造成的,还是weblogic服务器故障?我怎样才能找出这个堆栈跟踪的来源?
我知道这就是问题所在。我们正在使用一个名为cfg4j-core的库,每当运行下面的代码时,它都会使用java.util.Timer创建一个新的头。
它应该缓存属性30秒,但似乎没有工作。
结果创建的线程数总是增加,并以OutOfMemory结束。
ConfigFilesProvider configFilesProvider = new FilesPropertiesProvider(locations);
ConfigurationProvider configurationProvider = new ConfigurationProviderBuilder()
.withConfigurationSource(new FilesConfigurationSource(configFilesProvider))
.withReloadStrategy(new PeriodicalReloadStrategy(cacheSeconds, TimeUnit.SECONDS))
.build();
return configurationProvider.bind("config", SystemProperties.class);