版权声明:本文为博主原创文章,转载请注明出处。 https://blog.csdn.net/u012898245/article/details/80993014
平时使用map等集合的一个小优化。
这个问题小数据量的时候是体现不出来的,但是数据量变大的时候,很容易就会出现,就是java内存溢出的问题
java.lang.OutOfMemoryError:GC overhead limit exceeded
这个问题出现的时机就在程序运行的过程中,没有内存可分配了,也就是,有实例一直在占用内存,内存释放不了,很容易溢出了。这个需要研究一下java内存模型(这个我会补一个博客,留个坑先)。
解决这个问题可以增大运行内存,但是不是长久之计,数据越来越多的时候,内存总有消耗完的时候;代码优化才是第一部要分析的地方,比如走查代码有没有对象一直在占用的情况,太多没必要的创建对象。。。这些都会占用过多内存。
接下来我要说的是我优化过的一个小技巧。
先写一个不友好案例:
package com.optimization;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
/**
* 代码优化-->Map集合使用
* @author yushen
*
*/
public class CodeOptimization {
public static void main(String[] args) {
List<Map<String,String>> mapList = new LinkedList<>();
for(int i = 0;i<99999999l;i++){
mapList.add(returnMap());
}
System.out.println(mapList.size());
}
private static Map<String,String> returnMap(){
Map<String,String> map = new HashMap<>();
for (int i = 0; i < 20; i++) {
map.put(String.valueOf(i), "第"+i+"个值");
map.put("测试程序1","测试代码测试代码");
map.put("测试程序2","测试代码测试代码");
map.put("测试程序3","测试代码测试代码");
map.put("测试程序4","测试代码测试代码");
map.put("测试程序5","测试代码测试代码");
map.put("测试程序6","测试代码测试代码");
map.put("测试程序7","测试代码测试代码");
map.put("测试程序8","测试代码测试代码");
map.put("测试程序9","测试代码测试代码");
map.put("测试程序10","测试代码测试代码");
map.put("测试程序11","测试代码测试代码");
map.put("测试程序12","测试代码测试代码");
map.put("测试程序13","测试代码测试代码");
map.put("测试程序14","测试代码测试代码");
map.put("测试程序15","测试代码测试代码");
map.put("测试程序16","测试代码测试代码");
}
return map;
}
}
以上代码不友好的地方在于很快就会内存溢出,,,
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.lang.Integer.toString(Unknown Source)
at java.lang.String.valueOf(Unknown Source)
at com.optimization.CodeOptimization.returnMap(CodeOptimization.java:26)
at com.optimization.CodeOptimization.main(CodeOptimization.java:18)
原因在于这段代码一直在循环创建Map,导致内存占用过多,优化如下:
这个优化是有问题的,我还在找解决办法。。。
package com.optimization;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
/**
* 代码优化-->Map集合使用
* @author yushen
*
*/
public class CodeOptimization {
public static void main(String[] args) {
List<Map<String,String>> mapList = new LinkedList<>();
Map<String,String> map = new HashMap<>();
for(int i = 0;i<99999999l;i++){
mapList.add(returnMap(map));
}
System.out.println(mapList.size());
}
private static Map<String,String> returnMap(Map<String,String> map){
for (int i = 0; i < 20; i++) {
map.put(String.valueOf(i), "第"+i+"个值");
map.put("测试程序1","测试代码测试代码");
map.put("测试程序2","测试代码测试代码");
map.put("测试程序3","测试代码测试代码");
map.put("测试程序4","测试代码测试代码");
map.put("测试程序5","测试代码测试代码");
map.put("测试程序6","测试代码测试代码");
map.put("测试程序7","测试代码测试代码");
map.put("测试程序8","测试代码测试代码");
map.put("测试程序9","测试代码测试代码");
map.put("测试程序10","测试代码测试代码");
map.put("测试程序11","测试代码测试代码");
map.put("测试程序12","测试代码测试代码");
map.put("测试程序13","测试代码测试代码");
map.put("测试程序14","测试代码测试代码");
map.put("测试程序15","测试代码测试代码");
map.put("测试程序16","测试代码测试代码");
}
return map;
}
}
bingo,问题得到了解决,也就是Map的创建拿到循环外面,作为方法参数放进去,这样值会在循环里面更新,但是不会再循环创建,内存里在程序结束之前,Map只有一个。
小细节成就大事。