You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring响应式与非响应式内存占用对比及技术疑问

Spring 阻塞/响应式模型内存占用疑问

背景调研与测试

调研得知Spring响应式因Tomcat线程非阻塞,堆内存消耗应较低。采用Spring Data JPA传统阻塞非响应式模型测试该假设,代码如下:

@GetMapping("/customers")
public List<Customer> getAllCustomers() {
    long beforeUsedMem = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
    List<Customer> customerList = customerRepository.findAll(); // Your operation here
    long afterUsedMem = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
    System.out.println("Approximate memory used: " + (afterUsedMem - beforeUsedMem) + " bytes");

    return customerList;
}

查询数据库中200万条记录,测得customerList内存占用约1GB,输出:

Approximate memory used: 1371603632 bytes

技术疑问

  1. customerList是否存储在堆内存中?查询200万条记录并存储到列表是否会引发OOM错误?若当前内存足够避免崩溃,在无闲置内存时是如何解决内存问题的?本次运行代码未报错。
  2. 若采用如下响应式方式查询数据,内存占用是否会有优化?
@GetMapping("/")
public Flux<Customer> getCustomers() {
    return customerRepository.findAll()
            .doOnNext(customer -> System.out.println(customer.getCustomer_name()));
}

问题解答

针对疑问1的解答

  • customerList肯定存储在堆内存中:Java中所有对象实例(包括集合及其中的Customer对象)默认都分配在堆内存,除非使用了特殊堆外内存API,这里显然没有。
  • 查询200万条记录存入列表可能引发OOM:如果JVM堆内存不足以容纳这1GB左右的数据,就会抛出OutOfMemoryError。你这次没报错,只是当前JVM堆内存预留空间足够放下这些数据。
  • 无闲置内存时的处理逻辑:当堆内存不足时,JVM会先触发**垃圾回收(GC)**尝试释放不再使用的对象内存;如果GC后仍无足够空间分配新对象,才会抛出OOM错误。如果应用此时没有其他大对象占用内存,GC可能能腾出空间,但如果所有内存都被活跃对象占用(比如customerList还在被引用),必然会触发OOM。

针对疑问2的解答

响应式方式的内存占用会有明显优化,核心原因是Flux采用流式处理模型:

  • 传统阻塞模型中,customerRepository.findAll()会一次性把200万条记录全部加载到内存的List里,所有Customer对象同时存在于堆中,导致内存占用飙升。
  • 响应式模型中,Flux<Customer>不会一次性加载所有数据,而是按需流式获取:数据库驱动会分批从数据库拉取数据(比如每次拉取几百条),处理完当前批次的Customer(比如执行doOnNext的打印逻辑)后,这些对象就会失去引用,等待GC回收,再拉取下一批。整个过程中,堆里只会保留当前正在处理的少量Customer对象,内存占用会大幅降低(可能从GB级降到MB级)。

需要注意:这要求Spring Data JPA响应式实现(比如Spring Data R2DBC)支持流式查询,底层数据库驱动也要支持非阻塞流式读取,否则可能还是会一次性加载全部数据,达不到内存优化的效果。


内容的提问来源于stack exchange,提问作者trilocho

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 14:17:51