亚洲精品中文免费|亚洲日韩中文字幕制服|久久精品亚洲免费|一本之道久久免费

      
      

            <dl id="hur0q"><div id="hur0q"></div></dl>

                造輪子之MemorySafeLinkedBlockingQueue-LinkBlockingQueue改進

                LinkBlockingQueue改進

                問題背景

                https://github.com/apache/dubbo/pull/9722/files使用線程池的同學(xué)對于標(biāo)題中的隊列想必都有過使用,但上述隊列使用不當(dāng)時則會造成程序OOM,那怎么來控制呢?

                使用ArrayBlockingQueue?如何來評估長度?

                是否有一個完美的解決方案呢,MemorySafeLinkedBlockingQueue則通過對內(nèi)存的限制判斷盡面控制隊列的容量,完成解決了可能存在的OOM問題。

                獲取內(nèi)存大小(注:單位大B;支持準(zhǔn)實時更新):

                Runtime.getRuntime().freeMemory()//JVM中已經(jīng)申請到的堆內(nèi)存中還未使用的大小Runtime.getRuntime().maxMemory()// JVM可從操作系統(tǒng)申請到的最大內(nèi)存值 -XxmRuntime.getRuntime().totalMemory()// JVM已從操作系統(tǒng)申請到的內(nèi)存大小 —Xxs可設(shè)置該值大小-初始堆的大小

                線程池在excute任務(wù)時,放隊列,放不進去,使用新線程運行任務(wù)。這個放不進行,是使用的offer??非阻塞方法嗎?

                參考:https://blog.csdn.net/weixin_43108539/article/details/125190023

                public void execute(Runnable command) {if (command == null)throw new NullPointerException(); //拿到32位的intint c = ctl.get(); //工作線程數(shù)<核心線程數(shù)if (workerCountOf(c) < corePoolSize) {//進入if,代表可以創(chuàng)建 核心 線程數(shù)if (addWorker(command, true))return;//如果沒進入if,代表創(chuàng)建核心線程數(shù)失敗,重新獲取 ctlc = ctl.get();}//判斷線程池為Running狀態(tài),將任務(wù)添加入阻塞隊列,使用offerif (isRunning(c) && workQueue.offer(command)) {int recheck = ctl.get();//再次判斷是否為Running狀態(tài),若不是Running狀態(tài),remove任務(wù)if (! isRunning(recheck) && remove(command))reject(command);//如果線程池在Running狀態(tài),線程池數(shù)量為0else if (workerCountOf(recheck) == 0)//阻塞隊列有任務(wù),但是沒有工作線程,添加一個任務(wù)為空的工作線程處理阻塞隊列中的任務(wù)addWorker(null, false);}//阻塞隊列已滿,創(chuàng)建非核心線程,拒絕策略-addWorker中有判斷核心線程數(shù)是否超過最大線程數(shù)else if (!addWorker(command, false))reject(command);}

                空閑內(nèi)存計算

                package com.zte.sdn.oscp.queue;import cn.hutool.core.thread.NamedThreadFactory;import java.util.concurrent.Executors;import java.util.concurrent.ScheduledExecutorService;import java.util.concurrent.TimeUnit;import java.util.concurrent.atomic.AtomicBoolean;public class MemoryLimitCalculator {private static volatile long maxAvailable;private static final AtomicBoolean refreshStarted = new AtomicBoolean(false);private static void refresh() {maxAvailable = Runtime.getRuntime().freeMemory();}private static void checkAndScheduleRefresh() {if (!refreshStarted.get()) {// immediately refresh when first call to prevent maxAvailable from being 0// to ensure that being refreshed before refreshStarted being set as true// notice: refresh may be called for more than once because there is no lockrefresh();if (refreshStarted.compareAndSet(false, true)) {ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(new NamedThreadFactory(“Dubbo-Memory-Calculator”));// check every 50 ms to improve performancescheduledExecutorService.scheduleWithFixedDelay(MemoryLimitCalculator::refresh, 50, 50, TimeUnit.MILLISECONDS);Runtime.getRuntime().addShutdownHook(new Thread(() -> {refreshStarted.set(false);scheduledExecutorService.shutdown();}));}}}/** * Get the maximum available memory of the current JVM. * * @return maximum available memory */public static long maxAvailable() {checkAndScheduleRefresh();return maxAvailable;}/** * Take the current JVM’s maximum available memory * as a percentage of the result as the limit. * * @param percentage percentage * @return available memory */public static long calculate(final float percentage) {if (percentage1) {throw new IllegalArgumentException();}checkAndScheduleRefresh();return (long) (maxAvailable() * percentage);}/** * By default, it takes 80% of the maximum available memory of the current JVM. * * @return available memory */public static long defaultLimit() {checkAndScheduleRefresh();return (long) (maxAvailable() * 0.8);}}

                內(nèi)存安全隊列

                package com.zte.sdn.oscp.queue;import java.util.Collection;import java.util.concurrent.LinkedBlockingQueue;import java.util.concurrent.TimeUnit;public class MemorySafeLinkedBlockingQueue extends LinkedBlockingQueue {private static final long serialVersionUID = 8032578371739960142L;public static int THE_256_MB = 256 * 1024 * 1024;private int maxFreeMemory;private Rejector rejector;public MemorySafeLinkedBlockingQueue() {this(THE_256_MB);}public MemorySafeLinkedBlockingQueue(final int maxFreeMemory) {super(Integer.MAX_VALUE);this.maxFreeMemory = maxFreeMemory;//default as DiscardPolicy to ensure compatibility with the old versionthis.rejector = new DiscardPolicy();}public MemorySafeLinkedBlockingQueue(final Collection c, final int maxFreeMemory) {super(c);this.maxFreeMemory = maxFreeMemory;//default as DiscardPolicy to ensure compatibility with the old versionthis.rejector = new DiscardPolicy();}/** * set the max free memory. * * @param maxFreeMemory the max free memory */public void setMaxFreeMemory(final int maxFreeMemory) {this.maxFreeMemory = maxFreeMemory;}/** * get the max free memory. * * @return the max free memory limit */public int getMaxFreeMemory() {return maxFreeMemory;}/** * set the rejector. * * @param rejector the rejector */public void setRejector(final Rejector rejector) {this.rejector = rejector;}/** * determine if there is any remaining free memory. * * @return true if has free memory */public boolean hasRemainedMemory() {return MemoryLimitCalculator.maxAvailable() > maxFreeMemory;}@Overridepublic void put(final E e) throws InterruptedException {if (hasRemainedMemory()) {super.put(e);} else {rejector.reject(e, this);}}@Overridepublic boolean offer(final E e, final long timeout, final TimeUnit unit) throws InterruptedException {if (!hasRemainedMemory()) {rejector.reject(e, this);return false;}return super.offer(e, timeout, unit);}@Overridepublic boolean offer(final E e) {if (!hasRemainedMemory()) {rejector.reject(e, this);return false;}return super.offer(e);}}

                拒絕策略

                注意其中的rejector是拒絕策略,默認(rèn)的DiscardPolicy什么也不處理;

                而DiscardOldPolicy的處理邏輯很簡單

                public class DiscardOldestPolicy implements Rejector {@Overridepublic void reject(final E e, final Queue queue) {queue.poll();queue.offer(e);}}

                AbortPolicy則直接拋出異常

                public class AbortPolicy implements Rejector {@Overridepublic void reject(final E e, final Queue queue) {throw new RejectException(“no more memory can be used !”);}}

                個人建議增加日志打印即可。

                鄭重聲明:本文內(nèi)容及圖片均整理自互聯(lián)網(wǎng),不代表本站立場,版權(quán)歸原作者所有,如有侵權(quán)請聯(lián)系管理員(admin#wlmqw.com)刪除。
                用戶投稿
                上一篇 2022年9月9日 12:18
                下一篇 2022年9月9日 12:18

                相關(guān)推薦

                • 《光遇》11月25日紅石在哪里 11.25紅石位置

                  光遇11月25日的紅石出現(xiàn)在霞谷圓夢村,許多小伙伴都還不知道它具體在哪,下面就讓小編來給大家介紹一下光遇11.25紅石的位置,感興趣的小伙伴快來看看吧。 光遇11.25紅石位置 1…

                  2022年11月25日
                • 《光遇》11月25日每日任務(wù)怎么做 11.25每日任務(wù)攻略

                  光遇11月25日的日常任務(wù)現(xiàn)已更新,許多小伙伴還不知道今天的任務(wù)要怎么做,下面小編就給大家?guī)砹斯庥?1.25每日任務(wù)攻略,感興趣的小伙伴一起來看看吧。 光遇11.25每日任務(wù)攻略…

                  2022年11月25日
                • 什么是推廣cpa一篇文章帶你看懂CPA推廣渠道

                  CPA渠道 CPA指的是按照指定的行為結(jié)算,可以是搜索,可以是注冊,可以是激活,可以是搜索下載激活,可以是綁卡,實名認(rèn)證,可以是付費,可以是瀏覽等等。甲乙雙方可以根據(jù)自己的情況來定…

                  2022年11月25日
                • cpu性能天梯圖2022 AMD CPU天梯圖最新排行榜出爐

                  用戶在DIY自己的主機時選擇CPU是非常關(guān)鍵的,CPU可以說是電腦的大腦,大家也都想追求好一點的CPU來使用,但型號太多了,大部分的用戶都不知道目前哪一款CPU比較好用,快來看看詳…

                  2022年11月24日
                • 《魔獸世界》感恩節(jié)烹飪怎么做 2022感恩節(jié)烹飪速刷攻略

                  魔獸世界感恩節(jié)烹飪怎么做?關(guān)于本次感恩節(jié)活動不知道大家是否在參與,參與感恩節(jié)活動可以拿到不錯的獎勵,速刷感恩節(jié)烹飪?nèi)蝿?wù)很有必要,我們一起來看看。 魔獸世界2022感恩節(jié)烹飪速刷: …

                  2022年11月24日
                • 神舟十五號計劃近日擇機發(fā)射

                  本報北京11月21日電(中青報·中青網(wǎng)記者 邱晨輝)據(jù)中國載人航天工程辦公室消息,北京時間2022年11月21日,神舟十五號載人飛船與長征二號F遙十五運載火箭組合體已轉(zhuǎn)運至發(fā)射區(qū),…

                  2022年11月24日
                • 《戰(zhàn)神5》混沌之火怎么獲得?混沌之火獲得方法一覽

                  戰(zhàn)神5中一共有8個混沌之火,混沌之火可以用來升級玩家的武器,很多玩家想知道戰(zhàn)神5混沌之火怎么獲得,下面就帶來戰(zhàn)神5混沌之火獲得方法一覽,感興趣的小伙伴一起來看看吧,希望能幫助到大家…

                  2022年11月22日
                • 微信任務(wù)平臺(微信任務(wù)平臺源碼)

                  本文主要講的是微信任務(wù)平臺,以及和微信任務(wù)平臺源碼相關(guān)的知識,如果覺得本文對您有所幫助,不要忘了將本文分享給朋友。 微信推廣任務(wù)平臺哪個好? 對于微信推廣任務(wù)平臺的來說的話,我覺得…

                  2022年11月22日
                • 《光遇》11月21日每日任務(wù)怎么做 11.21每日任務(wù)攻略

                  光遇每天都會更新四個日常任務(wù),玩家完成任務(wù)可以獲得蠟燭獎勵,一些小伙伴還不知道今天的任務(wù)要怎么做,下面小編就給大家?guī)砹斯庥?1.21每日任務(wù)攻略,一起來看看吧。 光遇11.21每…

                  2022年11月21日
                • cpa項目操作的5種方式(cpa項目該如何操作)

                  新手怎樣操作cpa項目賺錢? 唯尚CPA聯(lián)盟2020-08-21 15:22:11 cpa項目并不是一個新的網(wǎng)絡(luò)賺錢項目,很多人已經(jīng)將這個項目做大做強,賺的盆滿缽滿了,但是也有很多…

                  2022年11月21日

                聯(lián)系我們

                聯(lián)系郵箱:admin#wlmqw.com
                工作時間:周一至周五,10:30-18:30,節(jié)假日休息