另外,我debug了一下netty的flush流程,在addFlush之后,進行doWrite的時候,會把整個鏈表的所有entry中的msg全都放到ByteBuffer(java原生)里(這也是我們進行兩次write再進行一次writeAndFlush或者flush時,會把之前兩次write的內容一起寫到socket里的原因),然后再通過原生channel寫出去,這里很多細節(jié),希望能展開講一下~
netty源碼分析之writeAndFlush全解析前言 在前面的文章中,我們已經詳細闡述了事件和異常傳播在netty中的實現,(netty源碼分析之pipeline(一),netty源碼分析之pipeline(二)),其中有...
這里有個問題,flush的時候,以NIO為例,doWrite會直接走到NioSocketChannel里,而不是AbstractNioByteChannel。
netty源碼分析之writeAndFlush全解析前言 在前面的文章中,我們已經詳細闡述了事件和異常傳播在netty中的實現,(netty源碼分析之pipeline(一),netty源碼分析之pipeline(二)),其中有...
@簡書閃電俠
謝謝謝謝。只是一個猜測。還是作者最有發(fā)言權
netty源碼分析之pipeline(一)通過前面的源碼系列文章中的netty reactor線程三部曲,我們已經知道,netty的reactor線程就像是一個發(fā)動機,驅動著整個netty框架的運行,而服務端的綁定和...
如果headContext不實現inboundhandler接口 invokeChannelRead接口需要這么寫:
if ( handler() instanceof HeadContext) {
(HeandContext)handler() . invokeRead
} else {
((ChannelInboundHandler) handler()).channelRead(this, msg);
}
需要對headcontext做特殊處理。這是不優(yōu)雅的,既然如此,就直接實現inboundhandler接口就好了~
netty源碼分析之pipeline(一)通過前面的源碼系列文章中的netty reactor線程三部曲,我們已經知道,netty的reactor線程就像是一個發(fā)動機,驅動著整個netty框架的運行,而服務端的綁定和...
或者說強轉出錯了。。。 括號中寫重復了
netty源碼分析之pipeline(一)通過前面的源碼系列文章中的netty reactor線程三部曲,我們已經知道,netty的reactor線程就像是一個發(fā)動機,驅動著整個netty框架的運行,而服務端的綁定和...
@簡書閃電俠
唔。我看了一下代碼。我覺得HeadContext實現inBound和outBound接口,實際是本身卻只是一個outBoundContext。這個原因要從fireChannelRead說起
AbstractChannelHandlerContext#invokeChannelRead方法,會執(zhí)行一個Handler的channelRead(在HeadContext里這個handler就是HeadContext自己),這個channelRead方法是inBoundHandler的方法。
作為讀的起始點,如果headContext不實現inBoundHandler,那么傳遞的時候,就不優(yōu)雅了。
因為執(zhí)行pipeline.fireChannelRead(byteBuf) -> AbstractChannelHandlerContext.invokeChannelRead(head, msg); -> ((ChannelInboundHandler) handler()).channelRead(this, msg) 這里最后一步,就走不通了(或者說不通用了)。
我反過來說,HeadContext不實現inboundhandler會怎樣。
private void invokeChannelRead(Object msg) {
if (invokeHandler()) {
try {
((ChannelInboundHandler) handler()).channelRead(this, msg);
} catch (Throwable t) {
notifyHandlerException(t);
}
} else {
fireChannelRead(msg);
}
}
這個方法中,(ChannelInboundHandler) handler()這一步就會直接報錯,這里的實現就會比較不優(yōu)雅。
總的來說,我認為,其實netty把head實現了inbound和outbound handler,但是卻只認為head是一個outbound的context,主要是為了:
1.能在執(zhí)行`invokeChannelRead`的時候,不用對headContext特殊處理
2.outBound就不用多說了,就是為了能讓數據流出的時候流經head節(jié)點。
netty源碼分析之pipeline(一)通過前面的源碼系列文章中的netty reactor線程三部曲,我們已經知道,netty的reactor線程就像是一個發(fā)動機,驅動著整個netty框架的運行,而服務端的綁定和...
為什么HeadContext實現了ChannelInboundHandler
但是在初始化時,卻把自己設置為 inbound = false?
netty源碼分析之pipeline(一)通過前面的源碼系列文章中的netty reactor線程三部曲,我們已經知道,netty的reactor線程就像是一個發(fā)動機,驅動著整個netty框架的運行,而服務端的綁定和...
可能是一種權衡,線程池保證提交的任務要優(yōu)先執(zhí)行。而且應該不存在空閑的線程,空閑的線程都在while循環(huán)里不停地從workQueue中取任務呢。。
深入分析java線程池的實現原理簡書 占小狼[http://www.itdecent.cn/users/90ab66c248e6/latest_articles] 轉載請注明原創(chuàng)出處,謝謝! 2019/...
最小值可能為0、1或者corePoolSize
深入分析java線程池的實現原理簡書 占小狼[http://www.itdecent.cn/users/90ab66c248e6/latest_articles] 轉載請注明原創(chuàng)出處,謝謝! 2019/...
補充一些東西。關于一個Worker如果從隊列中取不到task的情況(已經沒有任務可以執(zhí)行了)。
這個時候會執(zhí)行一個processWorkerExit的方法,這個方法先看worker退出的原因是不是由于用戶提交的任務中有異常,如果是,把worker的數量減一。
再從工作隊列中移除worker。
然后看看線程池是否是運行的。如果是運行的并且worker退出的原因是由于用戶任務中的異常,則新增一個worker(官方文檔上說是“替換”這個worker)。
如果不是,則根據allowCoreThreadTimeOut字段取和workQueue是否為空取一個最小值,最小值可能為0或者corePoolSize。如果工作的worker數量小于這個最小值,則同樣新增一個worker
深入分析java線程池的實現原理簡書 占小狼[http://www.itdecent.cn/users/90ab66c248e6/latest_articles] 轉載請注明原創(chuàng)出處,謝謝! 2019/...
jdk1.8并沒有出現“對象優(yōu)先在Eden分配”中示例的結果。
public class TestGC {
private static final int _1MB = 1024 * 1024;
private volatile static byte[] allocation1, allocation2, allocation3, allocation4;
/**
* VM參數:-verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails
* -XX:SurvivorRatio=8
*/
public static void testAllocation() {
allocation1 = new byte[2 * _1MB];
allocation2 = new byte[2 * _1MB];
allocation3 = new byte[2 * _1MB];
allocation4 = new byte[4 * _1MB]; // 出現一次Minor GC
}
public static void main(String[] args) throws IOException {
testAllocation();
System.in.read();
}
}
上述代碼的運行結果:
Heap
PSYoungGen total 9216K, used 7308K [0x00000007bf600000, 0x00000007c0000000, 0x00000007c0000000)
eden space 8192K, 89% used [0x00000007bf600000,0x00000007bfd23218,0x00000007bfe00000)
from space 1024K, 0% used [0x00000007bff00000,0x00000007bff00000,0x00000007c0000000)
to space 1024K, 0% used [0x00000007bfe00000,0x00000007bfe00000,0x00000007bff00000)
ParOldGen total 10240K, used 4096K [0x00000007bec00000, 0x00000007bf600000, 0x00000007bf600000)
object space 10240K, 40% used [0x00000007bec00000,0x00000007bf000010,0x00000007bf600000)
Metaspace used 2737K, capacity 4486K, committed 4864K, reserved 1056768K
class space used 298K, capacity 386K, committed 512K, reserved 1048576K
我們可以看到兩個結果:
1.并沒有發(fā)生gc,這是個好事
2.年輕代使用了89%,這里面應該有6mb是allocation1、2、3,而allocation4直接分配在了老年代(日志中顯示:老年代使用了40%)
看來新版的虛擬機把這個地方優(yōu)化了,上述情況不會進行一次YGC了
深入理解JVM(6) : Java對象內存分配策略Java技術體系中所提倡的自動內存管理最終可以歸結為自動化地解決了兩個問題:給對象分配內存以及回收分配給對象的內存。 對象的內存回收,可參考 java內存回收1 和 jav...
@如入心隨 像我學習就別了,哈哈哈,我就是個半吊子,一起努力!
我不以學校為驕傲,心懷感激就好畢業(yè)生晚會之后馬上就是答辯,然后就是離校,大學四年,走人連四天都不用。 今晚畢業(yè)生晚會,我本來以為我應該沒啥感觸,我有啥感觸呢!四年中一年半不在學校,半年不怎么上課,但是真到...
@如入心隨 電子商務。
我不以學校為驕傲,心懷感激就好畢業(yè)生晚會之后馬上就是答辯,然后就是離校,大學四年,走人連四天都不用。 今晚畢業(yè)生晚會,我本來以為我應該沒啥感觸,我有啥感觸呢!四年中一年半不在學校,半年不怎么上課,但是真到...