在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線(xiàn)課程
  • 觀(guān)看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

如何通過(guò)設(shè)計(jì)模式來(lái)節(jié)省內(nèi)存

科技綠洲 ? 來(lái)源:Java技術(shù)指北 ? 作者:Java技術(shù)指北 ? 2023-10-09 10:31 ? 次閱讀

相信大家日常開(kāi)發(fā)過(guò)程中,一個(gè)優(yōu)秀的程序猿寫(xiě)出的代碼一定要節(jié)省空間的,比如節(jié)省內(nèi)存,節(jié)省磁盤(pán)等等。那么如何通過(guò)設(shè)計(jì)模式來(lái)節(jié)省內(nèi)存呢?

1、什么是享元模式?

Use sharing to support large numbers of fine-grained objects efficiently.

享元模式(Flyweight Pattern):使用共享對(duì)象可有效地支持大量的細(xì)粒度的對(duì)象。

說(shuō)人話(huà):復(fù)用對(duì)象,節(jié)省內(nèi)存。

2、享元模式定義

圖片

①、Flyweight——抽象享元角色

是一個(gè)產(chǎn)品的抽象類(lèi), 同時(shí)定義出對(duì)象的外部狀態(tài)和內(nèi)部狀態(tài)的接口或?qū)崿F(xiàn)。

一個(gè)對(duì)象信息可以分為內(nèi)部狀態(tài)和外部狀態(tài)。

內(nèi)部狀態(tài) :對(duì)象可共享出來(lái)的信息, 存儲(chǔ)在享元對(duì)象內(nèi)部并且不會(huì)隨環(huán)境改變而改變,可以作為一個(gè)對(duì)象的動(dòng)態(tài)附加信息, 不必直接儲(chǔ)存在具體某個(gè)對(duì)象中, 屬于可以共享的部分。

外部狀態(tài) :對(duì)象得以依賴(lài)的一個(gè)標(biāo)記, 是隨環(huán)境改變而改變的、 不可以共享的狀態(tài)。

②、ConcreteFlyweight——具體享元角色

具體的一個(gè)產(chǎn)品類(lèi), 實(shí)現(xiàn)抽象角色定義的業(yè)務(wù)。該角色中需要注意的是內(nèi)部狀態(tài)處理應(yīng)該與環(huán)境無(wú)關(guān), 不應(yīng)該出現(xiàn)一個(gè)操作改變了內(nèi)部狀態(tài), 同時(shí)修改了外部狀態(tài), 這是絕對(duì)不允許的。

③、unsharedConcreteFlyweight——不可共享的享元角色

不存在外部狀態(tài)或者安全要求(如線(xiàn)程安全) 不能夠使用共享技術(shù)的對(duì)象, 該對(duì)象一般不會(huì)出現(xiàn)在享元工廠(chǎng)中。

④、FlyweightFactory——享元工廠(chǎng)

職責(zé)非常簡(jiǎn)單, 就是構(gòu)造一個(gè)池容器, 同時(shí)提供從池中獲得對(duì)象的方法。

3、享元模式通用代碼

/**
 * 抽象享元角色
 */
public abstract class Flyweight {
    // 內(nèi)部狀態(tài)
    private String instrinsic;

    // 外部狀態(tài) 通過(guò) final 修改,防止修改
    protected final String extrinsic;

    protected Flyweight(String extrinsic) {
        this.extrinsic = extrinsic;
    }

    // 定義業(yè)務(wù)操作
    public abstract void operate();

    public String getInstrinsic() {
        return instrinsic;
    }

    public void setInstrinsic(String instrinsic) {
        this.instrinsic = instrinsic;
    }
}
/**
 * 具體享元角色1
 */
public class ConcreteFlyweight1 extends Flyweight{

    protected ConcreteFlyweight1(String extrinsic) {
        super(extrinsic);
    }

    @Override
    public void operate() {
        System.out.println("具體享元角色1");
    }
}
/**
 * 具體享元角色2
 */
public class ConcreteFlyweight2 extends Flyweight{

    protected ConcreteFlyweight2(String extrinsic) {
        super(extrinsic);
    }

    @Override
    public void operate() {
        System.out.println("具體享元角色2");
    }
}
public class FlyweightFactory {
    // 定義一個(gè)池容器
    private static HashMap< String,Flyweight > pool = new HashMap<  >();

    // 享元工廠(chǎng)
    public static Flyweight getFlyweight(String extrinsic){
        // 需要返回的對(duì)象
        Flyweight flyweight = null;
        // 池中沒(méi)有該對(duì)象
        if(pool.containsKey(extrinsic)){
            flyweight = pool.get(extrinsic);
        }else{
            // 根據(jù)外部狀態(tài)創(chuàng)建享元對(duì)象
            flyweight = new ConcreteFlyweight1(extrinsic);
            // 放置到池中
            pool.put(extrinsic,flyweight);
        }
        return flyweight;
    }
}

4、通過(guò)享元設(shè)計(jì)文本編輯器

假設(shè)文本編輯器只包含文字編輯功能,而且只記錄文字和格式兩部分信息,其中格式包括文字的字體型號(hào)、大小、顏色等信息。

4.1 普通實(shí)現(xiàn)

通常設(shè)計(jì)是把每個(gè)文字看成一個(gè)單獨(dú)對(duì)象。

package com.itcoke.designpattern.flyweight.edittext;

/**
 * 單個(gè)文字對(duì)象
 */
public class Character {
    // 字符
    private char c;
    // 字體型號(hào)
    private String font;
    // 字體大小
    private int size;
    // 字體顏色
    private int colorRGB;

    public Character(char c, String font, int size, int colorRGB){
        this.c = c;
        this.font = font;
        this.size = size;
        this.colorRGB = colorRGB;
    }

    @Override
    public String toString() {
        return String.valueOf(c);
    }
}
/**
 * 編輯器實(shí)現(xiàn)
 */
public class Editor {
    private ArrayList< Character > chars = new ArrayList<  >();

    public void appendCharacter(char c, String font, int size, int colorRGB){
        Character character = new Character(c,font,size,colorRGB);
        chars.add(character);
    }

    public void display(){
        System.out.println(chars);
    }
}

客戶(hù)端:

public class EditorClient {
    public static void main(String[] args) {
        Editor editor = new Editor();
        editor.appendCharacter('A',"宋體",11,0XFFB6C1);
        editor.appendCharacter('B',"宋體",11,0XFFB6C1);
        editor.appendCharacter('C',"宋體",11,0XFFB6C1);
        editor.display();
    }
}

4.2 享元模式改寫(xiě)

上面的問(wèn)題很容易發(fā)現(xiàn),每一個(gè)字符就會(huì)創(chuàng)建一個(gè) Character 對(duì)象,如果是幾百萬(wàn)個(gè)字符,那內(nèi)存中就會(huì)存在幾百萬(wàn)的對(duì)象,那怎么去節(jié)省這些內(nèi)存呢?

其實(shí),分析一下,對(duì)于字體的格式,通常不會(huì)有很多,于是我們可以把字體格式設(shè)置為享元,也就是上面說(shuō)的可以共享的內(nèi)部狀態(tài)。

內(nèi)部狀態(tài)(共享):字體類(lèi)型、大小、顏色

外部狀態(tài)(不共享):字符

于是代碼改寫(xiě)如下:

public class CharacterStyle {
    // 字體型號(hào)
    private String font;
    // 字體大小
    private int size;
    // 字體顏色
    private int colorRGB;

    public CharacterStyle(String font, int size, int colorRGB) {
        this.font = font;
        this.size = size;
        this.colorRGB = colorRGB;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        CharacterStyle that = (CharacterStyle) o;
        return size == that.size &&
                colorRGB == that.colorRGB &&
                Objects.equals(font, that.font);
    }

    @Override
    public int hashCode() {
        return Objects.hash(font, size, colorRGB);
    }
}
public class CharacterStyleFactory {

    private static final Map< CharacterStyle,CharacterStyle > mapStyles = new HashMap<  >();

    public static CharacterStyle getStyle(String font, int size, int colorRGB){
        CharacterStyle newStyle = new CharacterStyle(font,size,colorRGB);

        if(mapStyles.containsKey(newStyle)){
            return mapStyles.get(newStyle);
        }
        mapStyles.put(newStyle,newStyle);
        return newStyle;
    }
}
public class Character {
    private char c;
    private CharacterStyle style;

    public Character(char c, CharacterStyle style) {
        this.c = c;
        this.style = style;
    }

    @Override
    public String toString() {
        return String.valueOf(c);
    }
}
public class Editor {
    private List< Character > chars = new ArrayList<  >();

    public void appendCharacter(char c, String font, int size, int colorRGB){
        Character character = new Character(c,CharacterStyleFactory.getStyle(font,size,colorRGB));
        chars.add(character);
    }

    public void display(){
        System.out.println(chars);
    }
}

5、享元模式在 java.lang.Integer 中應(yīng)用

看下面這段代碼,打印結(jié)果是啥?

public class IntegerTest {
    public static void main(String[] args) {
        Integer i1 = 56;
        Integer i2 = 56;
        Integer i3 = 129;
        Integer i4 = 129;
        System.out.println(i1 == i2); 
        System.out.println(i3 == i4); 
    }
}

圖片

為什么是這種結(jié)果呢?

首先說(shuō)一下 Integer i = 59;底層執(zhí)行了:Integer i = Integer.valueOf(59); 這是自動(dòng)裝箱。

int j = i; 底層執(zhí)行了:int j = i.intValue(); 這是自動(dòng)拆箱。

然后我們Integer.valueOf() 方法:

圖片

再看 IntegerCache 源碼:

private static class IntegerCache {
        static final int low = -128;
        static final int high;
        static final Integer cache[];

        static {
            // high value may be configured by property
            int h = 127;
            String integerCacheHighPropValue =
                sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
            if (integerCacheHighPropValue != null) {
                try {
                    int i = parseInt(integerCacheHighPropValue);
                    i = Math.max(i, 127);
                    // Maximum array size is Integer.MAX_VALUE
                    h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
                } catch( NumberFormatException nfe) {
                    // If the property cannot be parsed into an int, ignore it.
                }
            }
            high = h;

            cache = new Integer[(high - low) + 1];
            int j = low;
            for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++);

            // range [-128, 127] must be interned (JLS7 5.1.7)
            assert IntegerCache.high >= 127;
        }

        private IntegerCache() {}
    }

其實(shí)這就是我們前面說(shuō)的享元對(duì)象的工廠(chǎng)類(lèi),緩存 -128 到 127 之間的整型值,這是最常用的一部分整型值,當(dāng)然JDK 也提供了方法來(lái)讓我們可以自定義緩存的最大值。

6、享元模式優(yōu)點(diǎn)

減少應(yīng)用程序創(chuàng)建的對(duì)象, 降低程序內(nèi)存的占用, 增強(qiáng)程序的性能。

但它同時(shí)也提高了系統(tǒng)復(fù)雜性, 需要分離出外部狀態(tài)和內(nèi)部狀態(tài), 而且外部狀態(tài)具有固化特性, 不應(yīng)該隨內(nèi)部狀態(tài)改變而改變, 否則導(dǎo)致系統(tǒng)的邏輯混亂。

7、享元模式應(yīng)用場(chǎng)景

①、系統(tǒng)中存在大量的相似對(duì)象。

②、細(xì)粒度的對(duì)象都具備較接近的外部狀態(tài), 而且內(nèi)部狀態(tài)與環(huán)境無(wú)關(guān), 也就是說(shuō)對(duì)象沒(méi)有特定身份。

③、需要緩沖池的場(chǎng)景。

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀(guān)點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 內(nèi)存
    +關(guān)注

    關(guān)注

    8

    文章

    3055

    瀏覽量

    74334
  • 代碼
    +關(guān)注

    關(guān)注

    30

    文章

    4828

    瀏覽量

    69055
  • 設(shè)計(jì)模式
    +關(guān)注

    關(guān)注

    0

    文章

    53

    瀏覽量

    8655
  • 線(xiàn)程
    +關(guān)注

    關(guān)注

    0

    文章

    505

    瀏覽量

    19758
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    為了節(jié)省內(nèi)存OLED不使用全緩沖模式了.

    電源智慧辦公
    甘草酸不酸
    發(fā)布于 :2022年03月10日 15:12:17

    windowsXP系統(tǒng)如何節(jié)省內(nèi)存的方法

    windowsXP系統(tǒng)如何節(jié)省內(nèi)存的方法  XP系統(tǒng)節(jié)省內(nèi)存,加快開(kāi)機(jī)速度的方法如下:1.禁用壓縮文件夾功能,2.減少開(kāi)機(jī)磁盤(pán)掃描等待時(shí)間,重啟時(shí)候馬上你會(huì)看到效果。3.刪除系統(tǒng)備份文件,在各種
    發(fā)表于 02-26 15:40

    如何用PIC24FJ128GC010來(lái)設(shè)置EEPROM

    嗨,我正試圖使用數(shù)據(jù)EEPROM仿真與MYPIC24FJ128GC010,按此。但是,我發(fā)現(xiàn)我不能在編程之間節(jié)省內(nèi)存。在項(xiàng)目設(shè)置中(我使用MPLABX V3.30),我看不到設(shè)置EEPROM的設(shè)置
    發(fā)表于 04-29 14:04

    分享一個(gè)MCU省內(nèi)存的辦法

    1、聊一聊以前聽(tīng)這首曲子內(nèi)心會(huì)變得格外平靜,然而現(xiàn)在卻五味陳雜!今天主要跟大家分享一個(gè)MCU省內(nèi)存的辦法,同時(shí)也歡迎大家在文末問(wèn)答留言討論。2、讀前必備對(duì)于MCU...
    發(fā)表于 11-01 08:48

    分享一個(gè)MCU省內(nèi)存的辦法

    今天主要跟大家分享一個(gè)MCU省內(nèi)存的辦法,同時(shí)也歡迎大家在文末問(wèn)答留言討論。本文補(bǔ)充省內(nèi)存辦法1const的使用關(guān)于const的用法應(yīng)該是老生常談的知識(shí)點(diǎn)了,如果還有不是特別清楚的小伙伴可以參考一文
    發(fā)表于 11-03 06:58

    單片機(jī)開(kāi)發(fā)之節(jié)省內(nèi)存大法

    提點(diǎn)一下,我一說(shuō)估計(jì)很多人都清楚了,不過(guò)時(shí)間久了一些簡(jiǎn)單的知識(shí)沒(méi)有去使用或者重溫,到了解決問(wèn)題的時(shí)候還是容易卡殼,如果還沒(méi)有看過(guò)以前文章的可以到下面鏈接看看:?單片機(jī)開(kāi)發(fā)之節(jié)省內(nèi)存大法(...
    發(fā)表于 01-25 07:08

    ARM是怎樣使用多種低功耗模式來(lái)節(jié)省功耗的

    三種電源模式 :運(yùn)行、 睡眠、深度睡眠三種。一般而言,對(duì)于基于 ARM 架構(gòu)的 MCU 在系統(tǒng)或者電源復(fù)位之后,CPU 處于運(yùn)行狀態(tài)。當(dāng) CPU 不需要再繼續(xù)運(yùn)行時(shí),可以使用多種低功耗模式來(lái)節(jié)
    發(fā)表于 02-11 07:26

    iar build時(shí)出現(xiàn)內(nèi)存不夠的問(wèn)題

    單片機(jī)小白,語(yǔ)言是C,在用iar建工程的時(shí)候出現(xiàn)如圖錯(cuò)誤,根據(jù)其他提問(wèn)更改了優(yōu)化等級(jí)仍未解決,請(qǐng)問(wèn)還有其他解決方法嗎?或者有什么能優(yōu)化代碼節(jié)省內(nèi)存的算法舉例或者學(xué)習(xí)資料推薦?謝謝!
    發(fā)表于 03-26 21:49

    有沒(méi)有用tls省內(nèi)存的方案啊

    上傳文件走tls加密,測(cè)下來(lái)整個(gè)流程最大會(huì)分配50K內(nèi)存,這對(duì)于整個(gè)內(nèi)存只有80多k的單片機(jī)簡(jiǎn)直災(zāi)難,有沒(méi)有用tls省內(nèi)存的方案。
    發(fā)表于 09-30 10:07

    嵌入式系統(tǒng)節(jié)省內(nèi)存的解決方法

    嵌入式系統(tǒng)內(nèi)存往往是有限制的(成本考慮),因此需要盡量支持更多的功能,同時(shí)盡量減少使用的內(nèi)存
    的頭像 發(fā)表于 06-28 11:57 ?3286次閱讀
    嵌入式系統(tǒng)<b class='flag-5'>節(jié)省內(nèi)存</b>的解決方法

    【MCU】一種單片機(jī)節(jié)省內(nèi)存的方法(補(bǔ)充)

    1、聊一聊 以前聽(tīng)這首曲子內(nèi)心會(huì)變得格外平靜,然而現(xiàn)在卻五味陳雜! 今天主要跟大家分享一個(gè)MCU省內(nèi)存的辦法,同時(shí)也歡迎大家在文末問(wèn)答留言討論。2、讀前必備 對(duì)于MCU...
    發(fā)表于 10-26 19:51 ?14次下載
    【MCU】一種單片機(jī)<b class='flag-5'>節(jié)省內(nèi)存</b>的方法(補(bǔ)充)

    單片機(jī)單口不可用或被占用_【MCU】一種單片機(jī)節(jié)省內(nèi)存的方法

    今天主要跟大家分享一個(gè)MCU省內(nèi)存的辦法,同時(shí)也歡迎大家在文末問(wèn)答留言討論。本文補(bǔ)充省內(nèi)存辦法1const的使用 關(guān)于const的用法應(yīng)該是老生常談的知識(shí)點(diǎn)了,如果還有不是特別清楚的小伙伴可以
    發(fā)表于 10-28 16:21 ?15次下載
    單片機(jī)單口不可用或被占用_【MCU】一種單片機(jī)<b class='flag-5'>節(jié)省內(nèi)存</b>的方法

    Chrome將全面推出“節(jié)省內(nèi)存”和“節(jié)省電量”模式

    這個(gè)功能就像手機(jī)的 “超級(jí)省電模式”,適用于筆記本電腦電池電量不足,開(kāi)啟省電模式后,當(dāng)設(shè)備電池電量達(dá)到 20% 時(shí),Chrome 將通過(guò)限制后天活動(dòng)和帶動(dòng)畫(huà) / 視頻的網(wǎng)站的視覺(jué)效果來(lái)
    的頭像 發(fā)表于 12-12 14:44 ?942次閱讀

    如何使用Redis更節(jié)省內(nèi)存

    當(dāng)你的業(yè)務(wù)應(yīng)用在 Redis 中存儲(chǔ)數(shù)據(jù)很少時(shí),你可能并不太關(guān)心內(nèi)存資源的使用情況。但隨著業(yè)務(wù)的發(fā)展,你的業(yè)務(wù)存儲(chǔ)在 Redis 中的數(shù)據(jù)就會(huì)越來(lái)越多。
    的頭像 發(fā)表于 12-19 15:41 ?1000次閱讀

    如何通過(guò)在汽車(chē)子系統(tǒng)中共享麥克風(fēng)來(lái)節(jié)省空間和BOM成本

    電子發(fā)燒友網(wǎng)站提供《如何通過(guò)在汽車(chē)子系統(tǒng)中共享麥克風(fēng)來(lái)節(jié)省空間和BOM成本.pdf》資料免費(fèi)下載
    發(fā)表于 09-14 10:58 ?0次下載
    如何<b class='flag-5'>通過(guò)</b>在汽車(chē)子系統(tǒng)中共享麥克風(fēng)<b class='flag-5'>來(lái)</b><b class='flag-5'>節(jié)省</b>空間和BOM成本
    主站蜘蛛池模板: 女人张腿让男桶免费视频观看 | 激情爱爱的免费视频 | 狠狠干狠狠艹 | 女性私密部位扒开的视频 | 午夜一级免费视频 | 中年艳妇乱小玩 | 亚洲国产精品自在现线让你爽 | 四虎精品永久在线网址 | 欧美性色生活片天天看99 | 激情六月丁香 | 婷婷亚洲综合 | 爱爱免费 | 天天舔天天 | 5252欧美在线观看 | 亚洲欧美综合一区 | 女人张开腿让男人做爽爽 | 亚洲第一视频在线播放 | 午夜一级黄色片 | 成人免费午间影院在线观看 | 日本免费黄色片 | 国模视频在线 | 一区三区三区不卡 | 日本午夜大片免费观看视频 | 天天碰夜夜 | 黄网免费看 | 免费一级毛毛片 | 天堂网站 | 四虎最新紧急更新地址 | 黄色网在线看 | 77788色淫网站女女免费视频 | 国产精品一级香蕉一区 | 1314亚洲人成网站在线观看 | 一级毛片免费不卡直观看 | 免费网站毛片 | 色屋在线 | 午夜毛片视频 | 特级毛片免费视频播放 | 天天成人综合网 | 丁香六月婷婷精品免费观看 | 给我免费播放片黄色 | 成年色黄大色黄大片 视频 成年视频xxxxx免费播放软件 |