Spring 反应式内存使用与非反应式内存使用

问题描述 投票:0回答:1

根据我对 Spring Reactive 的研究,由于调用 Tomcat Web Server 的线程是非阻塞的,因此它不应该消耗太多堆内存。我正在尝试使用传统的阻塞非反应模型来使用 spring data jpa 检索数据来测试 ahat 假设。这是我的代码

 @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;
    }

我正在尝试测量 customerList 的大小(数据库中有 200 万条记录),其内存大约超过 1 GB 我的输出

Approximate memory used: 1371603632 bytes

我有两个问题希望有人能帮我解答。

  1. customerList 是否应该存储在堆内存中?检索 200 万条记录并将其存储在列表中是否会导致内存不足运行时错误?如果 GB 在防止崩溃方面发挥了作用,那么在这种情况下它如何解决内存问题,因为我们没有“未使用”的内存?当我运行代码时,它产生了良好的输出
  2. 如果我在检索数据时使用反应式风格
   @GetMapping("/")
   public Flux<Customer> getCustomers() {
       return customerRepository.findAll()
               .doOnNext(customer -> System.out.println(customer.getCustomer_name()));
   }

在内存使用方面会有任何改善吗?

java spring-boot spring-data-jpa jvm spring-webflux
1个回答
0
投票

我的堆的最大大小似乎是 4GB,所以我将最大堆大小更改为 1GB。看来阻塞模型会导致内存不足堆大小错误

    @GetMapping("/customers")
    public List<Customer> getAllCustomers() {
        long maxMemory = Runtime.getRuntime().maxMemory();
        System.out.println("Maximum Heap Size: " + maxMemory / (1024 * 1024) + " MB");
        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;
    }

当我更改为反应式非阻塞模型时,一切正常

    @GetMapping("/")
    public Flux<Customer> getCustomers() throws InterruptedException {
        long maxMemory = Runtime.getRuntime().maxMemory();
        System.out.println("Maximum Heap Size: " + maxMemory / (1024 * 1024) + " MB");
        Thread.sleep(5000);
        return customerRepository.findAll()
                .doOnNext(customer -> System.out.println(customer.getCustomer_name()));
    }

我很惊讶最大堆大小为 4 GB。 我想我可以得出一些关于在这种情况下使用反应式编程模型的优势的结论

© www.soinside.com 2019 - 2024. All rights reserved.