场景
从文件中读取 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以后也放在堆中)