锁定老帖子 主题:关于rails大容量网站部署的性能讨论
该帖已经被评为精华帖
|
|
---|---|
作者 | 正文 |
发表时间:2006-06-23
对同一个对象反复序列化,JVM会进行缓存,不管你循环20次,200次还是5000次,其实都是只序列化了一次,剩下的那只是循环本身的开销而已。如果你们真想得到最值得信赖的测试,那就应该真的去写一个web应用,用loadrunner去做压力测试,每个web页面去memcached取 session,然后再对比测试web页面不访问memcached,这样才行。
要测试的是并发情况下每个线程自己去序列化的开销,而不是单个线程对同一个Class的obj反复序列化的开销!!![b][/b] |
|
返回顶楼 | |
发表时间:2006-06-23
我认为,循环的测试中,属性值的改变,和实际的生产环境就很类似了。实际运行中,JVM中也是一个类有N多实例啊。Robin说的很对,我用loadrunnder测一次,这样才会比较放心。
|
|
返回顶楼 | |
发表时间:2006-06-23
真有趣亚,我用多线程试了一下
public static void main(String[] args); throws Exception { for (int i = 0; i < 400; i++); { final TestBean bean = new TestBean();; bean.setName("fankai" + i);; bean.setPass("fankai" + i);; bean.setAge(i);; new Thread(new Runnable(); { public void run(); { long start = System.currentTimeMillis();; try { testMethod(bean);; } catch (Exception e); { //e.printStackTrace();; } long end = System.currentTimeMillis();; System.out.println(end - start);; } });.start();; } } 发现前300个打出结果的线程从16ms到125ms都有,偶尔有0ms,而后一百个线程则都部分结果都是0,为什么呢? |
|
返回顶楼 | |
发表时间:2006-06-23
robbin 写道 对同一个对象反复序列化,JVM会进行缓存,不管你循环20次,200次还是5000次,其实都是只序列化了一次,剩下的那只是循环本身的开销而已。如果你们真想得到最值得信赖的测试,那就应该真的去写一个web应用,用loadrunner去做压力测试,每个web页面去memcached取 session,然后再对比测试web页面不访问memcached,这样才行。
要测试的是并发情况下每个线程自己去序列化的开销,而不是单个线程对同一个Class的obj反复序列化的开销!!![b][/b] 前面的这个例子中,每次循环用的都是new出来的TestBean,但结果还是一样的。 如果还是不行,用最恶的办法,做20个一模一样的类,从TestBean1--TestBean20,看看结果是31*20,还是接近i=20的情况。 |
|
返回顶楼 | |
发表时间:2006-06-23
我下周或者会找时间用真实的web应用连接memcached,然后用loadrunner测试一下效果,不过我对测试结果并不乐观。其实我也很希望序列化开销在可以接受的范围内。这样的话,Java也可以使用SNA架构,我也不必用apache搞那么麻烦的session sticky方案了,可以直接上lighttpd了。
|
|
返回顶楼 | |
发表时间:2006-06-23
粗略看了下代码,
1:序列化的开销主要是在初次序列化上,即一个类已经有对象被序列化过,那么以后再次序列化是几乎没有什么开销的。 2:因为有synchronized,所以在多线程情况大部分都开销在这个上面了,真正的序列化动作反而没什么开销。 |
|
返回顶楼 | |
发表时间:2006-06-23
序列化优化方案:
1:把所有需要序列化的对象的类提前初始化一次 2:自己实现writeObject那部分,去掉synchronized |
|
返回顶楼 | |
发表时间:2006-06-23
最野蛮暴力的测试:
import java.io.ByteArrayOutputStream; import java.io.ObjectOutputStream; import java.util.Date; public class SerializableTest { public static void testMethod(Object obj); throws Exception { ByteArrayOutputStream byteStream = new ByteArrayOutputStream();; ObjectOutputStream outStream = new ObjectOutputStream(byteStream);; outStream.writeObject(obj);; outStream.flush();; outStream.close();; byteStream.close();; } public static void main(String[] args); throws Exception { Long obj = new Long(1l);; testMethod(obj);; Date date = new Date();; testMethod(date);; TestBean bean = new TestBean();; bean.setName("fankai");; bean.setPass("fankai");; bean.setAge(30);; preClassLoad();; long start = System.currentTimeMillis();; for(int i=0;i<25;i++);{ testMethod2(i);; } long end = System.currentTimeMillis();; System.out.println("TestBean 25个对象序列化开销:"+ (end-start););; start = System.currentTimeMillis();; testMethod3();; end = System.currentTimeMillis();; System.out.println("25个不同类对象的初始化和序列化开销:" + (end-start););; } public static void testMethod2(int i); throws Exception { TestBean bean = new TestBean();; bean.setName("fankai");; bean.setPass("fankai");; bean.setAge(i);; ByteArrayOutputStream byteStream = new ByteArrayOutputStream();; ObjectOutputStream outStream = new ObjectOutputStream(byteStream);; outStream.writeObject(bean);; outStream.flush();; outStream.close();; byteStream.close();; } public static void testMethod3(); throws Exception { Object bean1 = new TestBean1("fankai","fankai",30);; Object bean2 = new TestBean2("fankai","fankai",30);; Object bean3 = new TestBean3("fankai","fankai",30);; Object bean4 = new TestBean4("fankai","fankai",30);; Object bean5 = new TestBean5("fankai","fankai",30);; Object bean6 = new TestBean6("fankai","fankai",30);; Object bean7 = new TestBean7("fankai","fankai",30);; Object bean8 = new TestBean8("fankai","fankai",30);; Object bean9 = new TestBean9("fankai","fankai",30);; Object bean10 = new TestBean10("fankai","fankai",30);; Object bean11 = new TestBean11("fankai","fankai",30);; Object bean12 = new TestBean12("fankai","fankai",30);; Object bean13 = new TestBean13("fankai","fankai",30);; Object bean14 = new TestBean14("fankai","fankai",30);; Object bean15 = new TestBean15("fankai","fankai",30);; Object bean16 = new TestBean16("fankai","fankai",30);; Object bean17 = new TestBean17("fankai","fankai",30);; Object bean18 = new TestBean18("fankai","fankai",30);; Object bean19 = new TestBean19("fankai","fankai",30);; Object bean20 = new TestBean20("fankai","fankai",30);; Object bean21 = new TestBean21("fankai","fankai",30);; Object bean22 = new TestBean22("fankai","fankai",30);; Object bean23 = new TestBean23("fankai","fankai",30);; Object bean24 = new TestBean24("fankai","fankai",30);; Object bean25 = new TestBean25("fankai","fankai",30);; testMethod(bean1);; testMethod(bean2);; testMethod(bean3);; testMethod(bean4);; testMethod(bean5);; testMethod(bean6);; testMethod(bean7);; testMethod(bean8);; testMethod(bean9);; testMethod(bean10);; testMethod(bean11);; testMethod(bean12);; testMethod(bean13);; testMethod(bean14);; testMethod(bean15);; testMethod(bean16);; testMethod(bean17);; testMethod(bean18);; testMethod(bean19);; testMethod(bean20);; testMethod(bean21);; testMethod(bean22);; testMethod(bean23);; testMethod(bean24);; testMethod(bean25);; } private static void preClassLoad();{ Object bean1 = new TestBean1("fankai","fankai",30);; Object bean2 = new TestBean2("fankai","fankai",30);; Object bean3 = new TestBean3("fankai","fankai",30);; Object bean4 = new TestBean4("fankai","fankai",30);; Object bean5 = new TestBean5("fankai","fankai",30);; Object bean6 = new TestBean6("fankai","fankai",30);; Object bean7 = new TestBean7("fankai","fankai",30);; Object bean8 = new TestBean8("fankai","fankai",30);; Object bean9 = new TestBean9("fankai","fankai",30);; Object bean10 = new TestBean10("fankai","fankai",30);; Object bean11 = new TestBean11("fankai","fankai",30);; Object bean12 = new TestBean12("fankai","fankai",30);; Object bean13 = new TestBean13("fankai","fankai",30);; Object bean14 = new TestBean14("fankai","fankai",30);; Object bean15 = new TestBean15("fankai","fankai",30);; Object bean16 = new TestBean16("fankai","fankai",30);; Object bean17 = new TestBean17("fankai","fankai",30);; Object bean18 = new TestBean18("fankai","fankai",30);; Object bean19 = new TestBean19("fankai","fankai",30);; Object bean20 = new TestBean20("fankai","fankai",30);; Object bean21 = new TestBean21("fankai","fankai",30);; Object bean22 = new TestBean22("fankai","fankai",30);; Object bean23 = new TestBean23("fankai","fankai",30);; Object bean24 = new TestBean24("fankai","fankai",30);; Object bean25 = new TestBean25("fankai","fankai",30);; } } 其中,TestBeanXX与TestBean一模一样,只有名字不同。为方便起见,搞了一个带参的构造函数。 发现一个非常奇怪的现象。如果在TestMethod3里面只有TestMethod(bean1)的时候,不同的执行,大概以2/3的概率为0,1/3的概率为15或16. 如果包含bean1/2,则0的概率小一些,16的概率有,也有31的情况 如果包含bean1-10,则出现16,31,47 如果包含bean1-25,则出现31,47,63这几种结果。63最多,47其次,偶尔有31 以63而言,平均的序列化时间为<3ms 一般情形 TestBean 25个对象序列化开销:31 25个不同类对象的初始化和序列化开销:62 这里面的水很深啊................ |
|
返回顶楼 | |
发表时间:2006-06-23
为了方便想试一下的同志,把那些个暴力类也贴出来
搞成附件了.但是不允许java扩展名.只能压缩了 |
|
返回顶楼 | |
发表时间:2006-06-23
开始一次的31ms是很正常的,做不了测试的结果。鬼知道jvm在初始这段时间做了什么。
for serial(new TestBean), avg time这个做的了结果。 |
|
返回顶楼 | |