根据我对 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
我有两个问题希望有人能帮我解答。
@GetMapping("/")
public Flux<Customer> getCustomers() {
return customerRepository.findAll()
.doOnNext(customer -> System.out.println(customer.getCustomer_name()));
}
在内存使用方面会有任何改善吗?
我的堆的最大大小似乎是 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。 我想我可以得出一些关于在这种情况下使用反应式编程模型的优势的结论