在线不卡日本ⅴ一区v二区_精品一区二区中文字幕_天堂v在线视频_亚洲五月天婷婷中文网站

  • <menu id="lky3g"></menu>
  • <style id="lky3g"></style>
    <pre id="lky3g"><tt id="lky3g"></tt></pre>

    造輪子之MemorySafeLinkedBlockingQueue-LinkBlockingQueue改進

    LinkBlockingQueue改進

    問題背景

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

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

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

    獲取內(nèi)存大?。ㄗⅲ簡挝淮驜;支持準實時更新):

    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可設置該值大小-初始堆的大小

    線程池在excute任務時,放隊列,放不進去,使用新線程運行任務。這個放不進行,是使用的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),將任務添加入阻塞隊列,使用offerif (isRunning(c) && workQueue.offer(command)) {int recheck = ctl.get();//再次判斷是否為Running狀態(tài),若不是Running狀態(tài),remove任務if (! isRunning(recheck) && remove(command))reject(command);//如果線程池在Running狀態(tài),線程池數(shù)量為0else if (workerCountOf(recheck) == 0)//阻塞隊列有任務,但是沒有工作線程,添加一個任務為空的工作線程處理阻塞隊列中的任務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是拒絕策略,默認的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),不代表本站立場,版權歸原作者所有,如有侵權請聯(lián)系管理員(admin#wlmqw.com)刪除。
    用戶投稿
    上一篇 2022年9月9日 12:18
    下一篇 2022年9月9日 12:18

    相關推薦

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

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

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

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

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

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

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

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

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

      魔獸世界感恩節(jié)烹飪怎么做?關于本次感恩節(jié)活動不知道大家是否在參與,參與感恩節(jié)活動可以拿到不錯的獎勵,速刷感恩節(jié)烹飪?nèi)蝿蘸苡斜匾覀円黄饋砜纯础?魔獸世界2022感恩節(jié)烹飪速刷: …

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

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

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

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

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

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

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

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

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

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

      2022年11月21日

    聯(lián)系我們

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