(原文出处需要通知作者)
文中摘取的链接和文章有:
1、之前写文件方式
环境:jdk1.6 ,eclipse、oracle11g
架构:后端mybatis、spring、dubbo、zookeeper;前端:工行cdui框架
具体任务:异步任务框架:前端插入插入一条数据到java端,之后将通过存过插入一条数据,异步任务线程扫描未处理的任务或者处理失败的任务,之后处理,各个机器同时去抢任务,
缺陷:插任务的时候没有标志字符,还不会修改。
之前写文件方式:无论是走mybatis里面的方式还是从存过方式取数据,都是全部取出来之后放到先放到List里面,存过方式的还要放到map中,之后写文件的时候,一直写完为止。不在中间进行flush处理,代码如内部电脑所示。修改后代码如修改后的代码所示:三种方式。
修改点:将读文件的方式修改为返回resultSet方式或者分批读数据,之后分批调用写文件构件写文件,并且在每200条的时候刷新一下,指导总思路模型:https://my.oschina.net/u/859433/blog/790833
具体操作如下:
- 1、优化取数据
- 执行mybati方式取数据的将之前的所有handler里面的方法和逻辑移植到从库里面取数据的公共方法中,每次返回10000条数据,直到100000条,存储过程方式取数据的方式采取返回resultSet的方式,返回数据;具体代码如类
- 其中 mybatis里面方式的开始也可以采取返回resultSet方式的,具体操作如链接:
mybatis流式查询: https://www.jianshu.com/p/0339c6fe8b61
- 具体实现是下面这篇博文:
MyBatis Stream方式读取SELECT超大结果集:
- 如果需要改造为map或者其他类型的接收数据库参数的方法是:https://www.cnblogs.com/LiuPan2016/p/8391753.html
但是在修改的时候需要升级为mybatis的3.4.0以上的版本,升级后需要加拦截器才能使用(可以实现)
但是现在的mybatis的其他调用数据库方法封装的在工行内部的ctp工程里面,mybatis需要添加拦截器,现在的技术能力不足以排查所有封装的insert、selectOne等具体实现,有技术风险,故没有采用;
- 为什么要加拦截器:
https://www.jianshu.com/p/ec40a82cae28(Mybatis之工作原理)
和https://blog.csdn.net/u014297148/article/details/78696096(具体拦截器工作位置)
- 加哪个拦截器:https://www.cnblogs.com/EasonJim/p/7056700.html
- 怎样加:http://www.mybatis.org/mybatis-3/zh/configuration.html和https://www.nowfox.com/article/5298和https://blog.csdn.net/freyaalisa/article/details/78596992
mybatis的物理分页:https://blog.csdn.net/leozhou13/article/details/50394242和
https://blog.csdn.net/bb188641864/article/details/78460266和
https://blog.csdn.net/abcd898989/article/details/51241089
mybatis的selectList的源码分析:https://www.cnblogs.com/xrq730/p/6955491.html
- 2、内存分析
java内存溢出,一般会有以下几个位置,堆、栈、方法区、直接内存。
在现在的工程中jdk使用1.6的情况下,java虚拟类型HostPot版本在永久代中实现方法区
- java内存模型:https://blog.csdn.net/javazejian/article/details/72772461(第一张图)
- 在linux上java内存如何分配:http://www.importnew.com/14486.html(查看在物理机器上的最大限额)
- 上文中的Java虚拟机-----方法区和运行时常量池:
https://blog.csdn.net/sunshine__me/article/details/49992909
https://www.cnblogs.com/redcreen/archive/2011/05/04/2036387.html
和https://www.cnblogs.com/junwangzhe/p/6282550.html
- 升级为jdk1.8之后java内存的变化:https://www.zhihu.com/question/49044988和https://www.cnblogs.com/paddix/p/5309550.html
- java程序上面看jvm参数的方法:https://blog.csdn.net/nieyinyin/article/details/7162009(查看最大可利用的堆内存)
- java代码和java内存之间的关系如下:https://blog.csdn.net/shimiso/article/details/8595564(提一下就行)
- 在linux和windows上面配置java虚拟机参数和gc回收算法的选择:https://blog.csdn.net/alinshen/article/details/74936275
- JVMGC——基本垃圾回收算法:https://blog.csdn.net/zhoudaxia/article/details/26946927和http://www.cnblogs.com/dolphin0520/p/3783345.html(多一个G1收集器)(提一下就行)
- 触发gc的条件:https://blog.csdn.net/yhyr_ycy/article/details/52566105和https://www.zhihu.com/question/41922036( Minor GC ,Full GC 触发条件)
- java堆中类和栈之间怎样引用:https://blog.csdn.net/wenbingoon/article/details/9102903
( 引用类型)
- 其中的weakReference的选用:http://puretech.iteye.com/blog/2008663和
- http://www.iteye.com/topic/401478
基于以上基础内容,现在就常见内存优化讲下:
- 3、jvm排查点和优化点:
- 选取jvm模式:https://www.cnblogs.com/haitaofeiyang/p/8336867.html和http://ryxxlong.iteye.com/blog/1696537(在开发工具中如何配置)和http://developer.51cto.com/art/201009/228035.htm(性能提升实验和硬件参数要求)
- OOM异常分类:https://blog.csdn.net/yuchao1076244056/article/details/51026551和https://www.jb51.net/article/110743.htm
- 导致的常见OOM问题解决办法:https://blog.csdn.net/spokenInChina/article/details/46779147和https://www.cnblogs.com/ygj0930/p/6522987.html和https://www.aliyun.com/jiaocheng/785134.html
和https://blog.csdn.net/wildandfly/article/details/32715013
和https://blog.csdn.net/bruce128/article/details/33745421 (说前两个就行)
直接内存导致的OOM问题:http://flychao88.iteye.com/blog/2188489,直接内存可以通过 -XX:MaxDirectMemorySize指定。如果本地直接内存溢出,我们可以发现堆转储快照中无明显异常指示,并且快照文件很小,而程序中又使用了NIO等技术,则可以检查是否直接内存溢出了
(下面的一直到 基于以上内容,现在就现在项目中的内存优化讲下 的不用讲)
和https://www.cnblogs.com/dingyingsi/p/3760447.html(其中涉及reference的方式和各种溢出的测试)
上文中的分代收集算法详细优化:https://blog.csdn.net/mccand1234/article/details/52078645
其中大部分为堆导致的OOM,检查代码中是否有死循环或递归调用为栈导致的OOM,
- result导致的内存溢出:mysql jdbc导致的内存溢出解决方法1:
https://www.aliyun.com/jiaocheng/1124488.html?spm=5176.100033.2.11.yVZhtc
解决方法2:http://antival.iteye.com/blog/1340774
解决方法3:https://blog.csdn.net/Apache012/article/details/16938895
oracle jdbc fetchsize取值对性能的影响,但过大对内存压力大:https://blog.csdn.net/chengly0129/article/details/49585947
jdbc全量优化(内含数据库优化):https://blog.csdn.net/seven_3306/article/details/9303879
关于oracle与mysql官方jdbc的一些区别:https://blog.csdn.net/seven_3306/article/details/9303979
JDBC进化史--从JDBC1.0到JDBC4.2: https://blog.csdn.net/u011179993/article/details/47291827
JDBC数据库连接池connection关闭后Statement和ResultSet未关闭的问题:https://blog.csdn.net/qiruiduni/article/details/39080053
ResultSet相关ResultSetMetaData详细:https://www.cnblogs.com/chinafine/articles/1847205.html
- 基于以上内容,现在就现在项目中的内存优化讲下:
- 改造前将数据拿出来后,放到ArrayList里面,之后再放到Map里面,ArrayList和Map的扩容机制是:http://www.cnblogs.com/skywang12345/p/3308900.html (4 容量增加方式不同)
hashMap:https://blog.csdn.net/u013309870/article/details/70456355和https://www.cnblogs.com/chenssy/p/3521565.html和
https://www.cnblogs.com/yanzige/p/8392142.html(只看着一个,一、什么时候扩容)
可能导致拿的数据量导致ArrayList扩容明显,Map扩容占用内存不明显,设置ArrayList为10w时,显示一直占用内存很大,不适用,见自己电脑上的图,
- io流选取
将Priwrite改为Buffered,防止java内存里面的数据没有刷新到内存中,见jdk源码,Priwrite一直在循环调用自己的Flush,没有刷新到内存里面的操作,Buffered有,
nio内容迁移到文章 nio技术和大文件写文件的方法
- oracle里面的改动:
现在配置不生效,不知道是不是Syscursor,cursor之间的区别:https://www.cnblogs.com/liuqiyun/p/6796740.html和https://blog.csdn.net/ocean42234111/article/details/53610253
cursor导致的错误解决方法(但是未解决):https://www.aliyun.com/jiaocheng/570370.html
修改设置 合理的fetchsize:https://blog.csdn.net/bincavin/article/details/8689186;
上文中的时间浪费在什么地方:https://www.cnblogs.com/sunsky303/p/8962628.html