socket內存佔用疑問?

寫一個程序想驗證伺服器在hold 1w個鏈接時內存情況。

1.先說下基本參數

web@haha ~&> cat /proc/sys/net/ipv4/tcp_rmem
4096 87380 4161536
web@haha ~&> cat /proc/sys/net/ipv4/tcp_wmem
4096 16384 4161536
web@haha ~&> cat /proc/sys/net/ipv4/tcp_mem
24180 32241 48360

2.測試環境

簡單的阿里雲伺服器,1核1G。。

3.測試代碼,java狗o(╯□╰)o,10000個鏈接去連本地的9090埠

final Selector selector = Selector.open();
InetSocketAddress addr = new InetSocketAddress("127.0.0.1", 9090);
long start = System.currentTimeMillis();
int connected = 0;
int currentConnectionPerIP = 0;
System.out.println("begin");
while (true) {
if (System.currentTimeMillis() - start &> 1000 * 60 * 10) {
break;
}
for (; currentConnectionPerIP &< 10000; currentConnectionPerIP++) { SocketChannel ch = SocketChannel.open(); ch.configureBlocking(false); Socket s = ch.socket(); s.setReuseAddress(true); ch.register(selector, SelectionKey.OP_CONNECT); ch.connect(addr); } int select = selector.select(1000 * 10); // 10s if (select &> 0) {
Set& selectedKeys = selector.selectedKeys();
Iterator& it = selectedKeys.iterator();

while (it.hasNext()) {
SelectionKey key = it.next();
if (key.isConnectable()) {
SocketChannel ch = (SocketChannel) key.channel();
if (ch.finishConnect()) {
++connected;
if (connected % (connectionPerIP / 10) == 0) {
System.out.println("connected: " + connected);
}
key.interestOps(SelectionKey.OP_READ);
}
}
}
selectedKeys.clear();
}
}

4.測試結果

web@haha ~&> cat /proc/net/sockstat
sockets: used 20251
TCP: inuse 20053 orphan 0 tw 10 alloc 20054 mem 3
UDP: inuse 7 mem 2
UDPLITE: inuse 0
RAW: inuse 0
FRAG: inuse 0 memory 0

代碼運行前內存

web@haha ~&> free -m
total used free shared buffers cached
Mem: 994 825 168 0 9 86
-/+ buffers/cache: 728 265
Swap: 0 0 0

代碼運行時內存

web@haha ~&> free -m
total used free shared buffers cached
Mem: 994 908 85 0 9 86
-/+ buffers/cache: 812 181
Swap: 0 0 0

5.疑問

為什麼內存才變化了80多M啊?這裡tcp socket內存大小我沒改啊,那就讀+寫=86+16,按100k來算的話,1w個鏈接不應該才消耗這麼少內存啊?


系統保留的是8K, 如果你所有的socket都一直很空閑 也都是發的小包 那麼socket的內存佔用就是8K

10000*8K 不是正好等於80M么~ 而且也說明你除了創建socket之外 也沒做其他需要消耗多內存的邏輯.


你這個實驗有兩個誤區:

1,理論上,tcp在完成握手後,如果你不進行後續操作,它是不會佔用資源的。你那個100KB就純粹開腦洞出來的。

2,選環回介面是不對的。參看《tcp/ip協議詳解 v1》第20頁,2.7小節:環回介面。

傳給環回地址(127.0.0.1)的任何數據均作為IP輸入,也就是數據根本沒經過鏈路層,而網路的不可靠就是來源於鏈路層中乙太網驅動故障以及多重路由轉髮帶來的誤碼和傳輸失敗,tcp就是為了解決這些,而你用這樣一個地址來測試tcp並發豈不是很可笑么。

建議的測試方法,在本地模擬tcp客戶端,鏈接阿里雲上面的服務端。


推薦閱讀:

圖解SDN:軟體定義網路導論篇
酷站推薦 - yunshan.net - 雲杉網路 | Pure Play SDN | 軟體定義網路
為什麼澳洲的網路又貴又慢?還沒有國內方便
外國大學的網路是否也會卡?
自治域AS是什麼東西?

TAG:計算機 | 計算機網路 | Socket | 網路編程 |