jetcache icon indicating copy to clipboard operation
jetcache copied to clipboard

caffeine报OutOfMemoryError: unable to create new native thread

Open anic opened this issue 2 months ago • 1 comments

请较一下大佬,是否见过运行时报异常java.lang.OutOfMemoryError: unable to create new native thread,应该如何处理?

详细堆栈

2025-09-29 15:08:20,695 1158228 [http-nio-0.0.0.0-8080-exec-12] WARN  c.g.b.c.cache.BoundedLocalCache com.github.benmanes.caffeine.cache.BoundedLocalCache:1434 - Exception thrown when submitting maintenance task 
java.lang.OutOfMemoryError: unable to create new native thread
	at java.lang.Thread.start0(Native Method)
	at java.lang.Thread.start(Thread.java:719)
	at java.util.concurrent.ForkJoinPool.createWorker(ForkJoinPool.java:1486)
	at java.util.concurrent.ForkJoinPool.tryAddWorker(ForkJoinPool.java:1517)
	at java.util.concurrent.ForkJoinPool.signalWork(ForkJoinPool.java:1634)
	at java.util.concurrent.ForkJoinPool.externalPush(ForkJoinPool.java:2414)
	at java.util.concurrent.ForkJoinPool.execute(ForkJoinPool.java:2648)
	at com.github.benmanes.caffeine.cache.BoundedLocalCache.scheduleDrainBuffers(BoundedLocalCache.java:1432)
	at com.github.benmanes.caffeine.cache.BoundedLocalCache.getIfPresent(BoundedLocalCache.java:1930)
	at com.github.benmanes.caffeine.cache.LocalManualCache.getIfPresent(LocalManualCache.java:57)
	at com.alicp.jetcache.embedded.CaffeineCache$2.getValue(CaffeineCache.java:67)
	at com.alicp.jetcache.embedded.AbstractEmbeddedCache.do_GET(AbstractEmbeddedCache.java:53)
	at com.alicp.jetcache.AbstractCache.GET(AbstractCache.java:87)
	at com.alicp.jetcache.MultiLevelCache.do_GET(MultiLevelCache.java:88)
	at com.alicp.jetcache.AbstractCache.GET(AbstractCache.java:87)
	at com.alicp.jetcache.AbstractCache.computeIfAbsentImpl(AbstractCache.java:137)
	at com.alicp.jetcache.AbstractCache.computeIfAbsent(AbstractCache.java:112)
	at com.alicp.jetcache.Cache.computeIfAbsent(Cache.java:311)
	at com.alicp.jetcache.SimpleProxyCache.computeIfAbsent(SimpleProxyCache.java:93)
	at com.alicp.jetcache.anno.method.CacheHandler.invokeWithCached(CacheHandler.java:245)
	at com.alicp.jetcache.anno.method.CacheHandler.doInvoke(CacheHandler.java:92)
	at com.alicp.jetcache.anno.method.CacheHandler.invoke(CacheHandler.java:84)
	at com.alicp.jetcache.anno.aop.JetCacheInterceptor.invoke(JetCacheInterceptor.java:74)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:241)
	at com.sun.proxy.$Proxy161.getSyResMap(Unknown Source)
	at com.demo.ResTypeManager.getResource(ResTypeManager.java:51)

对应代码是调用了添加了缓存注解的getSyResMap

public interface ISyResQueryService extends IBaseService {

    /**
     * 二级缓存时间
     */
    int CACHE_SECONDS = 600;

    /**
     * 一级缓存时间
     */
    int LOCAL_CACHE_SECONDS = 30;

    @Cached(name = "common:", key = "'resmap'", expire = CACHE_SECONDS, localExpire = LOCAL_CACHE_SECONDS, cacheType = CacheType.BOTH, localLimit = 10)
    Map<String, Boolean> getSyResMap();
}

使用配置

jetcache:
  areaInCacheName: false
  hidePackages: com.alibaba
  local:
    default:
      expireAfterWriteInMillis: 100000
      keyConvertor: fastjson
      limit: 100
      type: caffeine
  remote:
    default:
      uri: redis://${spring.redis.password}@${spring.redis.host}:${spring.redis.port}/${spring.redis.database}
      password: ${spring.redis.password}
      type: redis.lettuce
      keyConvertor: fastjson
      poolConfig:
        maxIdle: 20
        maxTotal: 50
        minIdle: 5
      valueDecoder: kryo
      valueEncoder: kryo
  statIntervalMinutes: 15

网上一种说法是caffeine的默认是使用ForkJoinPool, 当用于处理 IO 密集型任务,因为 IO 阻塞会让线程长期闲置但不释放,迫使池不断创建新线程。当线程数量超过操作系统的线程上限(如用户级限制 ulimit -u 或系统全局限制),就会触发 unable to create new native thread 错误。但我不知道对不对

而这个caffeine对象是jetcache创建的,本身没有指定线程池的配置项,因而导致创建的caffeine都是默认ForkJoinPool。

请大佬帮忙看看,原因是什么,应该如何解决?

anic avatar Oct 10 '25 08:10 anic

你的问题是内存溢出OutOfMemoryError,你应该去查内存溢出的原因,而不是看为什么最后一点点内存无法分配

areyouok avatar Oct 13 '25 02:10 areyouok