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 ...
随机推荐
- HTML jQuery 文档操作 - html() 方法
jQuery 文档操作 - html() 方法 jQuery 文档操作参考手册 实例 设置所有 p 元素的内容: $(".btn1").click(function(){ $(&q ...
- Java使用阿里云OSS对象存储上传图片
原 Java使用阿里云OSS对象存储上传图片 2017年03月27日 10:47:28 陌上桑花开花 阅读数 26804更多 分类专栏: 工作案例总结 版权声明:本文为博主原创文章,遵循CC 4.0 ...
- 分布式-信息方式-ActiveMQ的Message dispatch高级特性之(指针) Message cursors
Message dispatch高级特性之 Message cursors概述 ActiveMQ发送持久消息的典型处现方式是:当消息的消费者准备就绪时,消息发送系统把存储的 消息 ...
- Java常考面试题整理(一)
1.什么是java虚拟机?为什么java被称作是"平台无关的编程语言". 参考答案: java虚拟级是一个可以执行java字节码的虚拟机进程,java源文件被编译成能被java虚拟 ...
- 第八周学习总结&实验报告(6)
实验六 异常 一.实验目的: (1)理解异常的基本概念: (2)掌握异常处理方法及熟悉常见异常的捕获方法. 二.实验要求: (1)练习捕获异常.声明异常.抛出异常的方法.熟悉try和catch子句的使 ...
- VSCode安装go语言开发环境,go插件问题解决
在安装go插件时,会自动更新很多依赖库文件,都是从Github更新下来,但是因为Github的文件中,多有应用go官网中的文件,导致,因为网络缘故,不能直接下载,导致安装失败,如下: Instal ...
- leetcode-easy-string-28 Implement strStr()
mycode 77.15% class Solution(object): def strStr(self, haystack, needle): """ :type ...
- leetcode 118. Pascal's Triangle 、119. Pascal's Triangle II 、120. Triangle
118. Pascal's Triangle 第一种解法:比较麻烦 https://leetcode.com/problems/pascals-triangle/discuss/166279/cpp- ...
- logistic regression中的cost function选择
一般的线性回归使用的cost function为: 但由于logistic function: 本身非凸函数(convex function), 如果直接使用线性回归的cost function的话, ...
- rocketMQ 订阅关系
场景:2 个消费者进程中,创建了 2 个消费者,同属于 1 个消费组,但是订阅了不同的 topic,会因为订阅信息相互覆盖,导致拉不到消息. 原因是 rocketMQ 的订阅关系,是根据 group ...