系统的性能可以从吞吐量和响应性这两个方面考察。吞吐量衡量的是“有多少”,即限定资源的情况下,能够完成多少工作。响应性衡量的是“有多快”,即单个任务的处理时间。可以说吞吐量越大,响应越快,就表示系统的性能越好。
性能的这两个方面是完全分离的,有时候甚至是矛盾的。有人说软件设计就是权衡,其实我们能在很多地方看到对吞吐量和响应性的取舍。
1. Java gc算法的选择。Java -server缺省的gc算法是Parallel Collector,能够提高吞吐量,但是当你对响应时间更看重的时候,就需要选择Concurent Mark-Sweep(CMS)。
2. 线程上下文的切换。OS在线程上下文切换的时候会有系统开销,调度程序会为每一个可运行的线程分配一个最小执行时间,这样做是为了偿还线程切换的开销,获得更多不中断的执行时间,从整体上提高吞吐量,但这是以牺牲响应性为代价的。
3. Real-Time Java
实时系统,简单的说就是,能够在指定或者确定的时间内完成任务。系统的正确性不仅取决于系统计算结果的正确性.而且取决于正确结果产生的时间。
● “When” is as important as “what”
● “A late answer is a wrong answer”
real-time并不意味着一定比非实时“快”,而是强调执行时间的可预测性。普通Java不能做到实时,GC暂停是一个很重要的原因,因为这是开发人员无法控制和预测的因素。因此在Real-Time Java中,对GC的选择就是完全偏重于响应性。我们可以看一个对比:
对于SIP(Session Initiation Protocol) Server,实时系统的吞吐量比普通系统小,但对请求处理的延迟时间小,延迟大于50ms的只占0.3%。
2010年2月28日星期日
2010年1月29日星期五
Java中无符号数的处理
Java中int,short,byte都是有符号的,如果想处理无符号数,只有一个办法,用容量更大的类型替换,例如unsigned short就用int。唯一的例外是char,它本身就是无符号的,所以可以用char作为unsigned short。
那么从一个byte[]中怎么读取一个有符号的数呢?以unsigned short为例:
int unsignedShort ;
byte[] buf = getFromSomePlace();
int b1 = buf[0];
int b2 = buf[1];
unsignedShort = (((b1 & 0xff) << 8) | (b2 & 0xff))
那么,((b1 & 0xff) << 8)是什么意思呢?
首先, & 操作符会自动提升byte到int。
然后看b1&0xff的含义。大于2^15-1的无符号short,用两位byte表示,最高位为1。因为Java中都是有符号的数,最高位是符号位,为1表示负数。当byte扩充为int时,扩充位全都会变成1,b1 & 0xff就是将高位的1去掉。
最后是位移8位,和下一个byte拼接成unsigned short。
对于unsigned short,其实还可以用char存储:
char unsignedShort = (char) (b1 << 8 | b2);
我们去查看DataInput的javadoc,readUnsignedShort就是这样的。那位同学说了,我怎么去看DataInputStream的实现不是这样的,
public final int readUnsignedShort() throws IOException {
int ch1 = in.read();
int ch2 = in.read();
if ((ch1 | ch2) < 0)
throw new EOFException();
return (ch1 << 8) + (ch2 << 0);
}
没有什么&0xff。问题就在in.read()。InputStream的read方法返回的是int,从api描述可以看出:
Reads the next byte of data from the input stream. The value byte is returned as an int in the range 0 to 255.
可以看出,实际上返回的是一个无符号的byte,内部已经做了转换。我们可以看一个具体的实现,ByteArrayInputStream.read()
public int read() throws IOException {
if (closed) {
throw new IOException("Stream closed");
} else if (index >= limit) {
return -1; // EOF
} else {
return buffer[index++] & 0xff;
}
}
也就是说,Java中没有unsigned byte,InputStreamde read方法都统一返回int,所以DataInputStream中就不用再转换了。
那么从一个byte[]中怎么读取一个有符号的数呢?以unsigned short为例:
int unsignedShort ;
byte[] buf = getFromSomePlace();
int b1 = buf[0];
int b2 = buf[1];
unsignedShort = (((b1 & 0xff) << 8) | (b2 & 0xff))
那么,((b1 & 0xff) << 8)是什么意思呢?
首先, & 操作符会自动提升byte到int。
然后看b1&0xff的含义。大于2^15-1的无符号short,用两位byte表示,最高位为1。因为Java中都是有符号的数,最高位是符号位,为1表示负数。当byte扩充为int时,扩充位全都会变成1,b1 & 0xff就是将高位的1去掉。
最后是位移8位,和下一个byte拼接成unsigned short。
对于unsigned short,其实还可以用char存储:
char unsignedShort = (char) (b1 << 8 | b2);
我们去查看DataInput的javadoc,readUnsignedShort就是这样的。那位同学说了,我怎么去看DataInputStream的实现不是这样的,
public final int readUnsignedShort() throws IOException {
int ch1 = in.read();
int ch2 = in.read();
if ((ch1 | ch2) < 0)
throw new EOFException();
return (ch1 << 8) + (ch2 << 0);
}
没有什么&0xff。问题就在in.read()。InputStream的read方法返回的是int,从api描述可以看出:
Reads the next byte of data from the input stream. The value byte is returned as an int in the range 0 to 255.
可以看出,实际上返回的是一个无符号的byte,内部已经做了转换。我们可以看一个具体的实现,ByteArrayInputStream.read()
public int read() throws IOException {
if (closed) {
throw new IOException("Stream closed");
} else if (index >= limit) {
return -1; // EOF
} else {
return buffer[index++] & 0xff;
}
}
也就是说,Java中没有unsigned byte,InputStreamde read方法都统一返回int,所以DataInputStream中就不用再转换了。
订阅:
博文 (Atom)