今日码代码,用的列表(ArrayList)比较多,想到看过N多代码在能指明列表大小时而不指定,突然心血来潮,想用数据证明一下其危害性。
测试代码
package com.wm.memory;
import java.util.ArrayList;
public class ArrayListTest
{
static String ss;
static AtomicLong caps = new AtomicLong();
public static void main(String[] args) throws InterruptedException
{
ss = "1234567890";
Th th = new Th();
th.start();
while (true)
{
createMemory();
}
}
static void createMemory()
{
List<String> list = new ArrayList<String>(200); //* 指定列表大小
for (int i = 1; i <= 200; i++)
{
list.add(ss);
}
caps.incrementAndGet();
}
static class Th extends Thread
{
long pre = 0;
@Override
public void run()
{
try
{
while (true)
{
this.pre = caps.get();
Thread.sleep(1000);
System.out.println("caps " + (caps.get() - this.pre) + "p/s");
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
}
介绍:循环createMemory方法,计算单位时间内执行的次数。
指定list列表的长度为200时,见下图:
caps基本在64W左右,我的CPU是双核的,所以单线程下这算是跑满了。
不指定LIST长度时如下图:
caps是31W左右,基本上掉了一半。
为什么,翻开ArrayList.add里面的gow代码看一下:
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}
你的CPU就在不停的COPY COPY COPY,但String的这个COPY本身也没什么,也不会占什么内存,它只是拷指针
问题在于这么多COPY要循环 循环 循环,所以结果发现只会烧CPU不会烧内存。但如果LIST存的自己的Bean,又写了clone,那等着苦逼吧。