场景
从文件中读取 100w行一样的字符串,加到list,评测时间和内存和gc。
场景一,普通模式
List<TestBean> datas = Lists.newArrayList();
Runtime runtime = Runtime.getRuntime();
long memoryBefore = runtime.freeMemory();
Stopwatch stopwatch = Stopwatch.createStarted();
try (FileReader fileReader = new FileReader("data.txt");
BufferedReader bufferedReader = new BufferedReader(fileReader);) {
String line = null;
while ((line = bufferedReader.readLine())!=null) {
TestBean testBean = new TestBean();
testBean.name = line;
datas.add(testBean);
}
}
System.out.println("t:"+stopwatch.stop().elapsed(TimeUnit.MILLISECONDS));
System.out.println("m:"+(memoryBefore - runtime.freeMemory()));
System.out.println(datas.size());
场景二,String.intern
testBean.name = line.intern();
场景三,Guava的Interner
//声明一静态变量
static Interner<Object> objectInterner = Interners.newWeakInterner();
//修改
testBean.name = (String) objectInterner.intern(line);
测试结果
场景 | 参数 | 时间 | 内存 | gc |
---|---|---|---|---|
场景一 | -Xmx128m | 224 | 65346296 | 2次minor gc |
-Xmx32m | oom | |||
场景二 | -Xmx128m | 334 | 29105000 | 2次minor gc |
-Xmx32m | 1563 | 19714208 | 12次minor gc | |
场景三 | -Xmx128m | 222 | 29511112 | 2次minior gc |
-Xmx32m | 1751 | 24794176 | 12次minor gc |
结论
- 在内存足够的情况下,可以是用guava Interner,或者String.intern,或者不用,三者区别不大
- 在内存有限的情况下,可以考虑 guava Interner,或者String.intern
- String.intern只能用在String对象,而guava Interner可以任何非空的object
- guava Interner的对象可以是弱引用或是强引用放在内存中,而String.intern存放在常量表中(7以后也放在堆中)