形单影只的 Socket

最近工作上遇到过几次因 http client 没有配置超时相关参数,导致线程数占满或应用卡住的情况,出问题时线程的堆栈大致是这样的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
"qtp325266363-35729" #35729 prio=5 os_prio=0 tid=0x00007f5154033000 nid=0x1cf8f runnable [0x00007f4f7f511000]
java.lang.Thread.State: RUNNABLE
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
at java.net.SocketInputStream.read(SocketInputStream.java:171)
at java.net.SocketInputStream.read(SocketInputStream.java:141)
at sun.security.ssl.InputRecord.readFully(InputRecord.java:465)
at sun.security.ssl.InputRecord.read(InputRecord.java:503)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:983)
- locked <0x00000006e1494d68> (a java.lang.Object)
at sun.security.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:940)
at sun.security.ssl.AppInputStream.read(AppInputStream.java:105)
- locked <0x00000006e1496d88> (a sun.security.ssl.AppInputStream)
at org.apache.http.impl.conn.LoggingInputStream.read(LoggingInputStream.java:84)
at org.apache.http.impl.io.SessionInputBufferImpl.streamRead(SessionInputBufferImpl.java:137)
at org.apache.http.impl.io.SessionInputBufferImpl.fillBuffer(SessionInputBufferImpl.java:153)
at org.apache.http.impl.io.SessionInputBufferImpl.readLine(SessionInputBufferImpl.java:282)
at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:138)
at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:56)
at org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:259)
at org.apache.http.impl.DefaultBHttpClientConnection.receiveResponseHeader(DefaultBHttpClientConnection.java:163)

阅读全文

深入浅出垃圾回收(四)分代式 GC

上文介绍的增量式 GC 是对 mark 阶段的一大优化,可以极大避免 STW 的影响。本文将要介绍的分代式 GC 根据对象生命周期(后面称为 age)的特点来优化 GC,降低其性能消耗。

阅读本文需要熟悉之前提及的术语

阅读全文

深入浅出垃圾回收(三)增量式 GC

上一篇文章中介绍的 MS 优化策略都是围绕 sweep 阶段展开,但 mark 阶段会导致应用程序挂起,也就是常说的:stop-the-world(STW),这严重影响了 Tracing GC 的应用场景。本文即将介绍的增量式 GC 可以大大缓解 STW 问题。

阅读全文

深入浅出垃圾回收(二)Mark-Sweep 详析及其优化

在上一篇文中介绍的追踪类(tracing)GC 较引用计数(Reference Counting)性能更高,但原生的追踪类 GC 也有其自身缺点,需要对其进行改造才能真正的名副其实。这篇文章就来介绍与之相关的内容。

阅读全文

深入浅出垃圾回收(一)简介篇

GC 算法作为计算机科学领域非常热的研究话题之一,最早可追溯到 1959 年1,由 John McCarthy 在 Lisp 中实现来简化内存管理。早期的 Lisp 之所以被大众诟病慢,主要原因就是当时的 GC 实现相对简单,对程序的影响(overhead)比较严重。经过几十年的发展,GC 算法已经很成熟了,可以完全摆脱「速度慢」这个让人望而却步的标签。

阅读全文

2017 年终总结

2018 年不知不觉已经过了 20 天,从元旦开始就一直在重写之前的 History Master,其实这个插件一开始就是为了写年终总结,但功能相对较简单,经过这十几天的不断开发,算是脱胎换骨了,现在也可以好好写年终总结了。
一个词来形容 2017 的话,应该会是:变化。由于换了工作, 那就从工作开始谈起吧。

阅读全文

使用 ClojureScript 开发浏览器插件的过程与收获

随着 Firefox 57 的到来,之前维护的一个浏览器插件 gooreplacer 必须升级到 WebExtensions 才能继续使用,看了下之前写的 JS 代码,毫无修改的冲动,怕改了这个地方,那个地方突然就 broken 了。因此,这次选择了 cljs,整体下来流程很顺利,除了迁移之前的功能,又加了更多功能,希望能成为最简单易用的重定向插件 :-)

阅读全文

由浅入深学习 Lisp 宏之实战篇

本文是宏系列的第二篇文章,侧重于实战,对于新手建议先阅读宏系列的理论篇,之后再来看本文。当然如果你有一定基础,也可以直接阅读本文。
其次,希望读者能把本文的 Clojure 代码手动敲到 REPL 里面去运行、调试,直到完全理解。

阅读全文

由浅入深学习 Lisp 宏之理论篇

宏(macro)是 Lisp 语言中最重要的武器,它可以自动生成运行时的代码。宏也是编写领域特定语言(DSL)的利器,可以在不改动语言本身的基础上,增加新的程序构造体,这在其他语言中是不可能。比如,现在比较流行的同步方式写异步代码的 async/await,在非 Lisp 语言需要语言本身支持,但是在 Lisp 里面可以通过几个宏来解决,可以参考:core.async

阅读全文

《硅谷之谜》读后感

吴军博士的《硅谷之谜》 在年前就买了,可是一直迟迟没翻开。最近在一次出差的动车上把它看完了,可以说是一气呵成,根本停不下来,里面介绍的很多观点都比较深刻,而不仅仅是简单的罗列事实,更像是科学探究,试图找出每一个事情背后的原理。

阅读全文