随笔 - 5, 文章 - 0, 评论 - 0, 引用 - 0
数据加载中……

2012年10月23日

HttpAsyncClient

HttpAsyncClient 是一个异步的 HTTP 客户端开发包,基于 HttpCore NIO 和 HttpClient 组件。
HttpAsyncClient 的出现并不是为了替换 HttpClient,而是作为一个补充用于需要大量并发连接,对性能要求非常高的基于HTTP的原生数据通信,而且提供了事件驱动的 API。

代码示例:

       public Vector<Long> Gets(List<String> urls)
throws IOReactorException, InterruptedException {
List<HttpGet> requests = new ArrayList<HttpGet>();
for (String url : urls) {
HttpGet get = new HttpGet(url);
requests.add(get);
}
final Vector<Long> dataPackages = new Vector<Long>();
HttpAsyncClient httpclient = new DefaultHttpAsyncClient();
httpclient.getParams().setIntParameter("http.socket.timeout", 5000)
.setIntParameter("http.connection.timeout", 5000)
.setIntParameter("http.socket.buffer-size", 8192)
.setBooleanParameter("http.tcp.nodelay", true);
final CountDownLatch latch = new CountDownLatch(requests.size());
httpclient.start();
try {
for (final HttpGet request : requests) {
httpclient.execute(request, new FutureCallback<HttpResponse>() {

@Override
public void completed(HttpResponse result) {
String statInfo = "";
try {
statInfo = result.getFirstHeader("statInfo").getValue();
if (statInfo != null) {
Long size = Long.parseLong(statInfo.split(",")[0].split(":")[1]);
dataPackages.add(size);
}
} catch (Exception e) {
System.out.println(e);
System.out.println(statInfo);
}
latch.countDown();
}

@Override
public void failed(Exception ex) {
latch.countDown();
}

@Override
public void cancelled() {
latch.countDown();
}
});
}
latch.await();
} finally {
httpclient.shutdown();
}
return dataPackages;
}

 


依赖的pom,
httpasyncclient已经有4.0-beta3版本了
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpasyncclient</artifactId>
    <version>4.0-beta1</version>
</dependency>
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.2-beta1</version>
</dependency>


posted @ 2012-11-26 10:46 庄主游骥 阅读(615) | 评论 (0)编辑 收藏

web.xml页面配置

     摘要: web.xml页面配置参数详解         加载顺序与它们在 web.xml 文件中的先后顺序无关。即不会因为 filter 写在 listener 的前面而会先加载 filter。最终得出的结论是:listener -> filter -> servlet。  同时还存在着这样一种配置节...  阅读全文

posted @ 2012-11-13 11:37 庄主游骥 阅读(3182) | 评论 (0)编辑 收藏

gc 对象晋升old区的一些规则总结

ygc做步骤为:清空eden+from中所有no ref的对象占用的内存
将eden+from中的所有存活的对象copy到to中
在这个过程中一些对象将晋升到old中:
--to放不下的
--存活次数超过tenuring threshold的
重新计算Tenuring Threshold

然后谈谈MaxTenuringThreshold这个参数用于控制对象能经历多少次Minor GC才晋升到旧生代,默认值是15,那是不是意味着对象要经历15次minor gc才晋升到旧生代呢,来看下面的一个例子。

public class GCTenuringThreshold{
public static void main(String[] args) throws Exception{
GCMemoryObject object1=new GCMemoryObject(2);
GCMemoryObject object2=new GCMemoryObject(8);
GCMemoryObject object3=new GCMemoryObject(8);
GCMemoryObject object4=new GCMemoryObject(8);
object2=null;
object3=null;
GCMemoryObject object5=new GCMemoryObject(8);
Thread.sleep(4000);
object2=new GCMemoryObject(8);
object3=new GCMemoryObject(8);
object2=null;
object3=null;
object5=null;
GCMemoryObject object6=new GCMemoryObject(8);
Thread.sleep(5000);
}
}
class GCMemoryObject{
private byte[] bytes=null;
public GCMemoryObject(int multi){
bytes=new byte[1024*256*multi];
}
}

以-Xms20M –Xmx20M –Xmn10M –XX:+UseSerialGC参数执行以上代码,通过jstat -gcutil [pid] 1000 10的方式查看执行效果,很惊讶执行结果竟然是在第二次minor GC的时候object1就被晋升到old中了,而可以肯定的是这个时候to space空间是充足的,也就是说并不是在to space空间充足的情况下,对象一定要经历MaxTenuringThreshold次才会晋升到old,那具体规则到底是怎么样的呢,翻看 Hotspot 6 update 21中SerialGC的实现,可以看到在每次minor GC后,会对这个存活周期的阈值做计算,计算的代码如下:

size_t desired_survivor_size = (size_t)((((double) survivor_capacity)*TargetSurvivorRatio)/100);
size_t total = 0;
int age = 1;
assert(sizes[0] == 0, "no objects with age zero should be recorded");
while (age total += sizes[age];
// check if including objects of age 'age' made us pass the desired
// size, if so 'age' is the new threshold
if (total > desired_survivor_size) break;
age++;
}
int result = age
其中desired_survivor_size是指survivor space/2,从上面的代码可看出,在计算存活周期这个阈值时,hotspot会遍历所有age的table,并对其所占用的大小进行累积,当累积的大 小超过了survivor space的一半时,则以这个age作为新的存活周期阈值,最后取age和MaxTenuringThreshold中更小的一个值。

按照这样的规则,上面的运行效果就可验证了,第一次minor gc的时候存活周期的阈值为MaxTenuringThreshold,minor gc结束后计算出新的阈值为1,在第二次minor gc时object 1的age已经是1了,因此object1被晋升到了旧生代。

这个规则对于Serial GC以及ParNew GC(但对于开启了UseAdaptiveSizePolicy的ParNew GC而言也无效,默认是不开启的)均有效,对于PS(Parallel Scavenge) GC而言,在默认的情况下第一次以InitialTenuringThreshold(默认为7)为准,之后在每次minor GC后均会动态计算,规则比上面的复杂,在设置-XX:-UseAdaptiveSizePolicy后,则以 MaxTenuringThrehsold为准,并且不会重新计算,会是恒定值。

如希望跟踪每次minor GC后新的存活周期的阈值,可在启动参数上增加:-XX:+PrintTenuringDistribution,输出的信息中的:
Desired survivor size 1048576 bytes, new threshold 7 (max 15)
new threshold 7即标识新的存活周期的阈值为7。

posted @ 2012-10-23 20:52 庄主游骥 阅读(819) | 评论 (0)编辑 收藏