仓酷云

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 4049|回复: 19
打印 上一主题 下一主题

[学习教程] JAVA网页编程之Java String的序列化小结仓酷云

[复制链接]
小魔女 该用户已被删除
跳转到指定楼层
楼主
发表于 2015-1-18 11:29:30 | 显示全部楼层 回帖奖励 |倒序浏览 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
你通过从书的数量和开发周期及运行速度来证明:net网页编程和ruby要比java简单。String对我们来讲太熟习了,由于它无处不在,更由于用String能够形貌这个天下几近一切的工具,乃至于为了形貌准确的数值都必要String出马(由于盘算机眼中的二进制和人类眼中的十进制间总有那末点隔阂)。由于熟习而变得复杂,也简单被疏忽。明天纪录一下关于String的简单被疏忽的两个成绩。


  • 字符串重用——节俭内存
由于字符串太多,假如可以重用则可以节俭很年夜的内存。起首看上面一个例子:
Stringstring1=“HELLOHELLO”;

Stringstring2=“HELLO”+“HELLO”;
下面创立了几个字符串?1or2?后者是静态创立的,不外信任JVM能够对其间接优化的,由于编译时已晓得内容了,推测是一个instance,即统一个char数组。Heapdump出来后察看公然是一个。
Stringstring3=args[0]+args[1];
输出参数HELLO HELLO? 字符串酿成几个?没错啊,是两个HELLOHELLO了。Dumpheap后察看,公然是两个了。(实在不必dumphealp,debug也能够看出来,string1和string3中的char[]指向地点是纷歧样的)。
依此延长,能够而知由java反序列化而来的那些string也是纷歧样的。实比方下;
publicfinalstaticvoidmain(String[]args)throwsException{

newStringDeserialized().testDescirialized();

}

publicvoidtestDescirialized()throwsException{

StringtestString=“HELLOHELLO”;

ObjectOutputStreamdataOutStream=newObjectOutputStream(newFileOutputStream(“./stringdeserialized.data”));

for(inti=0;i<1000;i++)

dataOutStream.writeObject(testString);

dataOutStream.close();

List<String>readAgainList=newArrayList<String>(100);

for(inti=0;i<100;i++){

ObjectInputStreamdataInputStream=newObjectInputStream(newFileInputStream(“./stringdeserialized.data”));

readAgainList.add((String)dataInputStream.readObject());

dataInputStream.close();

}

Thread.sleep(Integer.MAX_VALUE);

}


<br>
截图是heapdump出来的,有HELLOHELLO的个数有101个,占用的size>8080。关于JVM的内存利用可参考http://www.javamex.com/tutorials/memory/object_memory_usage.shtml
成绩来了,体系保护的数据年夜多是字符串信息,好比configserver,而良多的信息都是统一个字符串,那末重复的从收集序列化而来,占用多的Heap。固然本人能够写一个weakhashmap来保护,重用这些字符串。人人晓得JVM中有StringPool,利用它无疑最好不外。查找String源码,发明intern()的正文以下:
*Whentheinternmethodisinvoked,ifthepoolalreadycontainsa

*stringequaltothis<code>String</code>objectasdeterminedby

*the{@link#equals(Object)}method,thenthestringfromthepoolis

*returned.Otherwise,this<code>String</code>objectisaddedtothe

*poolandareferencetothis<code>String</code>objectisreturned.

因而改动下面一行代码为:
readAgainList.add(((String)dataInputStream.readObject()).intern());
再次Heapdump剖析以下,别的能够看出一个包括10个字符的String占用的Heap是80byte:

<br>


  • 字符串序列化的速率
今朝CS处置为了撑持所谓的恣意范例数据,CS接纳了一个技能,用Swizzle来保留java序列化后的byte范例,Server端无需反序列化就可以保留恣意范例的data;如许的害处有两个:通用的Java序列化效力不高;协定欠亨用,对其他言语撑持不可。由于今朝的数据信息基础都是String范例,而对对String数据的专门处置,能够经由过程String外部的byte数组(UTF-8)类暗示,如许也便于其他言语剖析。能够思索增添对publish(String)的撑持。因而做了以下测试来对照对String分歧serialize/deserialize的速度和巨细。
了局是writeUTF最小最快,关于100char的String,差异是数目级的相称分明,固然Swizzle利用了一个技能,当对统一个swizzleinstance屡次传输时,无需反复的序列化。
PS:Swizzle复杂的说就是把信息包装起来,然后把序列化的byte流缓存起来,如许假如一样的一个信息要推送/发送N次,就能干削减N-1次的序列化工夫。

publicclassCompareSerialization{

publicStringgenerateTestData(intstringLength){

Randomrandom=newRandom();

StringBuilderbuilder=newStringBuilder(stringLength);

for(intj=0;j<stringLength;j++){

builder.append((char)random.nextInt(127));

}

returnbuilder.toString();

}

publicinttestJavaDefault(Stringdata)throwsException{

ObjectOutputStreamoutputStream=null;

ObjectInputStreaminputStream=null;

try{

ByteArrayOutputStreambyteArray=newByteArrayOutputStream();

outputStream=newObjectOutputStream(byteArray);

outputStream.writeObject(data);

outputStream.flush();

inputStream=newObjectInputStream(newByteArrayInputStream(byteArray.toByteArray()));

inputStream.readObject();

returnbyteArray.size();

}

finally{

outputStream.close();

inputStream.close();

}

}

publicinttestJavaDefaultBytes(Stringdata)throwsException{

ObjectOutputStreamoutputStream=null;

ObjectInputStreaminputStream=null;

try{

ByteArrayOutputStreambyteArray=newByteArrayOutputStream();

outputStream=newObjectOutputStream(byteArray);

outputStream.writeBytes(data);

outputStream.flush();

inputStream=newObjectInputStream(newByteArrayInputStream(byteArray.toByteArray()));

byte[]bytes=newbyte[byteArray.size()];

inputStream.read(newbyte[byteArray.size()]);

newString(bytes);

returnbyteArray.size();

}

finally{

outputStream.close();

inputStream.close();

}

}

publicinttestSwizzle(Swizzledata)throwsException{

ObjectOutputStreamoutputStream=null;

ObjectInputStreaminputStream=null;

try{

ByteArrayOutputStreambyteArray=newByteArrayOutputStream();

outputStream=newObjectOutputStream(byteArray);

outputStream.writeObject(data);

outputStream.flush();

inputStream=newObjectInputStream(newByteArrayInputStream(byteArray.toByteArray()));

inputStream.readObject();

returnbyteArray.size();

}

finally{

outputStream.close();

inputStream.close();

}

}

publicinttestStringUTF(Stringdata)throwsException{

ObjectOutputStreamoutputStream=null;

ObjectInputStreaminputStream=null;

try{

ByteArrayOutputStreambyteArray=newByteArrayOutputStream();

outputStream=newObjectOutputStream(byteArray);

outputStream.writeUTF(data);

outputStream.flush();

inputStream=newObjectInputStream(newByteArrayInputStream(byteArray.toByteArray()));

inputStream.readUTF();

returnbyteArray.size();

}

finally{

outputStream.close();

inputStream.close();

}

}

publicfinalstaticvoidmain(String[]args)throwsException{

CompareSerializationcompare=newCompareSerialization();

Stringdata=compare.generateTestData(Integer.parseInt(args[0]));

Swizzleswizzle=newSwizzle(data);

System.out.println(“testJavaDefaultsizeonnetworking:”+compare.testJavaDefault(data));

System.out.println(“testJavaDefaultBytessizeonnetworking:”+compare.testJavaDefaultBytes(data));

System.out.println(“testStringUTFsizeonnetworking:”+compare.testStringUTF(data));

System.out.println(“testSwizzlesizeonnetworking:”+compare.testSwizzle(swizzle));

//warmup

for(inti=0;i<100;i++){

compare.testJavaDefault(data);

compare.testJavaDefaultBytes(data);

compare.testStringUTF(data);

compare.testSwizzle(swizzle);

}

longstartTime=System.currentTimeMillis();

for(inti=0;i<10000;i++){

compare.testJavaDefault(data);

}

longendTime=System.currentTimeMillis();

System.out.println(“testJavaDefaultusingtime:”+(endTime&ndash;startTime));

startTime=System.currentTimeMillis();

for(inti=0;i<10000;i++){

compare.testJavaDefaultBytes(data);

}

endTime=System.currentTimeMillis();

System.out.println(“testJavaDefaultBytesusingtime:”+(endTime&ndash;startTime));

startTime=System.currentTimeMillis();

for(inti=0;i<10000;i++){

compare.testStringUTF(data);

}

endTime=System.currentTimeMillis();

System.out.println(“testStringUTFusingtime:”+(endTime&ndash;startTime));

startTime=System.currentTimeMillis();

for(inti=0;i<10000;i++){

compare.testSwizzle(swizzle);

}

endTime=System.currentTimeMillis();

System.out.println(“testSwizzleusingtime:”+(endTime&ndash;startTime));

}

}


java比较简单,没有C++的烦琐,但学习时最好有C++为基础.与JSP和SQL起应用,功能强大.
小魔女 该用户已被删除
沙发
 楼主| 发表于 2015-5-4 17:49:25 | 显示全部楼层
所以现在应用最广泛又最好学的就是J2EE了。 J2EE又包括许多组件,如Jsp,Servlet,JavaBean,EJB,JDBC,JavaMail等。要学习起来可不是一两天的事。那么又该如何学习J2EE呢?当然Java语法得先看一看的,I/O包,Util包,Lang包你都熟悉了吗?然后再从JSP学起。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|仓酷云 鄂ICP备14007578号-2

GMT+8, 2024-5-3 16:24

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表