tensorflow+java 内存泄漏修复
2021/5/25 7:27:08
本文主要是介绍tensorflow+java 内存泄漏修复,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
前段时间java程序,内存泄漏比较严重,平均3-5天就要重启一下,赶快分析原因。从公司的监控看到,主要是对外内存泄漏,因为堆内存泄漏不是很严重。所以决定优先处理前者。因为该项目是java开发的,主要任务时加载tensorflow1.*的模型,并实时预测。其实主要JNI调用c++接口,所以很大可能是在接口调用时泄漏了,看代码:
Tensor res =null; try { List<String> colname=IntColname; Runner rlt = sess.runner(); for(int i=0; i<intvalue[0].length; i++) { int[][] index=new int[intvalue.length][1]; for(int m=0; m<intvalue.length; m++) { index[m][0]=intvalue[m][i]; } Tensor indexTensor = Tensor.create(index); rlt.feed(colname.get(i), indexTensor); } colname=FloatColname; for(int i=0; i<floatvalue[0].length; i++) { float[][] index=new float[floatvalue.length][1]; for(int m=0; m<floatvalue.length; m++) { index[m][0]=floatvalue[m][i]; } Tensor indexTensor = Tensor.create(index); rlt.feed(colname.get(i), indexTensor); temp.add(indexTensor); } res=rlt.fetch("output").run().get(0); float[][] finalRlt = new float[intvalue.length][1]; res.copyTo(finalRlt); List<Float> result=new ArrayList<Float>(); for(int i=0; i<finalRlt.length; i++) { result.add(finalRlt[i][0]); } return result; } catch (Exception e) { logger.error("",e); }finally { if (res != null) { res.close(); } }
虽然res调用了close方法,但是 indexTensor 却没有调用,因此调整代码。
Tensor res =null; List<Tensor> temp=new ArrayList<>(); try { List<String> colname=IntColname; Runner rlt = sess.runner(); for(int i=0; i<intvalue[0].length; i++) { int[][] index=new int[intvalue.length][1]; for(int m=0; m<intvalue.length; m++) { index[m][0]=intvalue[m][i]; } Tensor indexTensor = Tensor.create(index); rlt.feed(colname.get(i), indexTensor); temp.add(indexTensor); } colname=FloatColname; for(int i=0; i<floatvalue[0].length; i++) { float[][] index=new float[floatvalue.length][1]; for(int m=0; m<floatvalue.length; m++) { index[m][0]=floatvalue[m][i]; } Tensor indexTensor = Tensor.create(index); rlt.feed(colname.get(i), indexTensor); temp.add(indexTensor); } res=rlt.fetch("output").run().get(0); float[][] finalRlt = new float[intvalue.length][1]; res.copyTo(finalRlt); List<Float> result=new ArrayList<Float>(); for(int i=0; i<finalRlt.length; i++) { result.add(finalRlt[i][0]); } return result; } catch (Exception e) { logger.error("",e); }finally { if (res != null) { res.close(); } for(int i=0; i<temp.size(); i++) { Tensor t=temp.get(i); if(t!=null) { t.close(); } } }
主要是增加temp队列回收临时变量。上线后发现泄漏不是很严重了,说明很有效果。不过还有,后面是java堆内存泄漏,发现每次泄漏的时间正是模型切换的时间,因此大概率是模型切换的代码有问题,上代码。
public static void clearCache() { logger.info("===model clear==="); sess=null; }
这里的session就是模型解析好的session会话,由下面的代码生成。
byte[] graphBytes = IOUtils.toByteArray(inputStream); Graph graph=new Graph(); graph.importGraphDef(graphBytes); sess = new Session(graph);
立刻明白,上面的代码有问题,调整为如下:
public static void clearCache() { logger.info("===model clear==="); if(sess!=null) { logger.info("destory session"); sess.close(); sess=null; } }
少了一个close,造成session关联的对象无法释放,至此内存泄漏问题算是解决了。
这篇关于tensorflow+java 内存泄漏修复的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-26消息中间件源码剖析教程
- 2024-11-26JAVA语音识别项目资料的收集与应用
- 2024-11-26Java语音识别项目资料:入门级教程与实战指南
- 2024-11-26SpringAI:Java 开发的智能新利器
- 2024-11-26Java云原生资料:新手入门教程与实战指南
- 2024-11-26JAVA云原生资料入门教程
- 2024-11-26Mybatis官方生成器资料详解与应用教程
- 2024-11-26Mybatis一级缓存资料详解与实战教程
- 2024-11-26Mybatis一级缓存资料详解:新手快速入门
- 2024-11-26SpringBoot3+JDK17搭建后端资料详尽教程