java.lang.StackOverflowError解决
在使用JPA的仓储repository进行查询时,经常用到findAllbyId的方法: repository.findAllbyId()
但如果像下面的代码,当list的size量太大的话,就会报栈溢出的的错误:java.lang.StackOverflowError
@RequestMapping("/stackOverFlow")
public Integer stackOverFlow() {
List<String> ids = new ArrayList<>();
for (int i = 0; i < 5000; i++) {
ids.add("123123123123");
}
List<BillDO> allById = dwBillRepository.findAllById(ids);
return allById.size();
}
报错信息如下:
Caused by: java.lang.StackOverflowError
at antlr.BaseAST.toString(BaseAST.java:333) ~[antlr-2.7.7.jar:?]
at antlr.BaseAST.toStringList(BaseAST.java:341) ~[antlr-2.7.7.jar:?]
at antlr.BaseAST.toStringList(BaseAST.java:347) ~[antlr-2.7.7.jar:?]
at antlr.BaseAST.toStringList(BaseAST.java:347) ~[antlr-2.7.7.jar:?]
at antlr.BaseAST.toStringList(BaseAST.java:347) ~[antlr-2.7.7.jar:?]
at antlr.BaseAST.toStringList(BaseAST.java:347) ~[antlr-2.7.7.jar:?]
at antlr.BaseAST.toStringList(BaseAST.java:347) ~[antlr-2.7.7.jar:?]
at antlr.BaseAST.toStringList(BaseAST.java:347) ~[antlr-2.7.7.jar:?]
at antlr.BaseAST.toStringList(BaseAST.java:347) ~[antlr-2.7.7.jar:?]
at antlr.BaseAST.toStringList(BaseAST.java:347) ~[antlr-2.7.7.jar:?]
at antlr.BaseAST.toStringList(BaseAST.java:347) ~[antlr-2.7.7.jar:?]
原因就是在拼sql时方法入栈太深,超过了jvm允许的最大深度,也就是递归调用的太深了。
public String toStringList() {
String var2 = "";
if (this.getFirstChild() != null) {
var2 = var2 + " (";
}
var2 = var2 + " " + this.toString();
if (this.getFirstChild() != null) {
var2 = var2 + ((BaseAST)this.getFirstChild()).toStringList();
}
if (this.getFirstChild() != null) {
var2 = var2 + " )";
}
if (this.getNextSibling() != null) {
var2 = var2 + ((BaseAST)this.getNextSibling()).toStringList();
}
return var2;
}
解决方法就是不要递归的太深。或者调整JVM参数栈大小默认为1m,可以调整到10m,看看不能解决问题,但这样做不推荐。会影响线程数,从而影响系统性能。
具体到上面的问题就是一次不要查太多的数据。如果in的数量有5000,我们就分开查询一次只查1000,查5次。再把结果组合在一起。
如果每个业务都单独写的话,就太麻烦了,可以写个公共的方法,如下: JPA_QUERY_LIST_MAX_SIZE是一个常量数据值,如1000个查一次。这里使用了并行查询,查询效率更高。
public <T> List<T> findAll(List<String> ids, Function<List<String>, List<T>> func) {
List<List<String>> idGroups = Lists.partition(ids, JPA_QUERY_LIST_MAX_SIZE);
ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(idGroups.size());
executor.setKeepAliveTime(10, TimeUnit.SECONDS);//解决线程不退出的问题
executor.allowCoreThreadTimeOut(true);
return idGroups
.stream()
.collect(ParallelCollectors
.parallelToList(i -> func.apply(i), executor, idGroups.size()))
.join()
.stream()
.flatMap(Collection::stream)
.collect(toList());
}
以上代码利用如一个第三方的库:需要引用:
<dependency>
<groupId>com.pivovarit</groupId>
<artifactId>parallel-collectors</artifactId>
<version>1.1.0</version>
</dependency>
这里引出一个题外话,如果in查询数据量很大的话,可能会导致索引失效的问题。需要重点看一下。
java.lang.StackOverflowError解决的更多相关文章
- java.lang.StackOverflowError 解决方法
♦ java.lang.StackOverflowError : 由于深度递归,抛出此错误以指示应用程序的堆栈已耗尽. 在递归中,一个方法在执行期间调用自己.递归被认为是一种强大的通用编程技术,但必须 ...
- java.lang.StackOverflowError 解决办法
java.lang.StackOverflowError com.sxt.servlet.servlet1.LoginServlet.doGet(LoginServlet.java:15) com.s ...
- Spark出现java.lang.stackoverflowerror的解决方法
正在测试的程序需要多次迭代(400+次),每次迭代有复杂的运算 迭代到100多次的时候报java.lang.stackoverflowerror的错误 解决方法:先checkpoint()再count ...
- struts2 java.lang.StackOverflowError org.apache.struts2.json.JSONWriter
1. 问题描述: 页面通过异步访问action, action的方法通过map封装数据,struts的result的type设置为json,后台报错 六月 25, 2016 6:54:33 下午 ...
- android布局太深导致的 java.lang.StackOverflowError
E/AndroidRuntime( 1900): java.lang.StackOverflowError E/AndroidRuntime( 1900): at android.graphi ...
- 【转】java.lang.StackOverflowError
http://blog.csdn.net/g19920917/article/details/8765638 出现一个java.lang.StackOverflowError异常.弄了半天,又是问高手 ...
- servlet运行“/*”引起的java.lang.StackOverflowError
<servlet> <servlet-name>login</servlet-name> <servlet-class>com.jd.login.UI. ...
- Java EE之Hibernate异常总结【5】java.lang.StackOverflowError[栈溢出]
Exception in thread "main" java.lang.StackOverflowError at java.lang.reflect.InvocationTar ...
- android java.lang.StackOverflowError
转自:http://hi.baidu.com/424660053/item/bee53a2633870dccddf69a17 最近做项目出现一个java.lang.StackOverflowError ...
随机推荐
- TopCoder SRM 667 Div.2题解
概览: T1 枚举 T2 状压DP T3 DP TopCoder SRM 667 Div.2 T1 解题思路 由于数据范围很小,所以直接枚举所有点,判断是否可行.时间复杂度O(δX × δY),空间复 ...
- 关于JavaScript的内存机制
一.背景 var a = 20; var b = 'abc'; var c = true; var d = { m: 20 } 因为JavaScript具有自动垃圾回收机制,所以对于前端开发来说,内存 ...
- Springboot 项目中引入WebSocket后,单元测试出现错误
报错信息 java.lang.IllegalStateException: Failed to load ApplicationContext at org.springframework.test. ...
- 第九周学习总结&实验报告七
实验报告: 实验任务详情: 完成火车站售票程序的模拟. 要求: (1)总票数1000张: (2)10个窗口同时开始卖票: (3)卖票过程延时1秒钟: (4)不能出现一票多卖或卖出负数号票的情况. 实验 ...
- LeetCode 300. 最长上升子序列(Longest Increasing Subsequence)
题目描述 给出一个无序的整形数组,找到最长上升子序列的长度. 例如, 给出 [10, 9, 2, 5, 3, 7, 101, 18], 最长的上升子序列是 [2, 3, 7, 101],因此它的长度是 ...
- 定时刷新指定div层
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/ ...
- SpringBoot整合kafka(安装)
项目路径:https://github.com/zhaopeng01/springboot-study/tree/master/study_14 序言 Kafka 是一种高吞吐的分布式发布订阅消息系统 ...
- node 常用模块
像在服务器上的操作,我们只要 require 引入的模块,只要不是 nodejs 中的模块,我们的下载环境都是开发环境 配置自动化:引用插件 nodemon 下载:npm i nodemon -g ...
- leetcode-easy-trees-98. Validate Binary Search Tree-NO
mycode 不会 注意:root的值要比左子树上所有的数大 参考 # Definition for a binary tree node. # class TreeNode(object): # ...
- HOG + SVM(行人检测, opencv实现)
HOG+SVM流程 1.提取HOG特征 灰度化 + Gamma变换(进行根号求解) 计算梯度map(计算梯度) 图像划分成小的cell,统计每个cell梯度直方图 多个cell组成一个block, 特 ...