色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

如何通過設計模式來節省內存

科技綠洲 ? 來源:Java技術指北 ? 作者:Java技術指北 ? 2023-10-09 10:31 ? 次閱讀

相信大家日常開發過程中,一個優秀的程序猿寫出的代碼一定要節省空間的,比如節省內存,節省磁盤等等。那么如何通過設計模式來節省內存呢?

1、什么是享元模式?

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

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

說人話:復用對象,節省內存。

2、享元模式定義

圖片

①、Flyweight——抽象享元角色

是一個產品的抽象類, 同時定義出對象的外部狀態和內部狀態的接口或實現。

一個對象信息可以分為內部狀態和外部狀態。

內部狀態 :對象可共享出來的信息, 存儲在享元對象內部并且不會隨環境改變而改變,可以作為一個對象的動態附加信息, 不必直接儲存在具體某個對象中, 屬于可以共享的部分。

外部狀態 :對象得以依賴的一個標記, 是隨環境改變而改變的、 不可以共享的狀態。

②、ConcreteFlyweight——具體享元角色

具體的一個產品類, 實現抽象角色定義的業務。該角色中需要注意的是內部狀態處理應該與環境無關, 不應該出現一個操作改變了內部狀態, 同時修改了外部狀態, 這是絕對不允許的。

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

不存在外部狀態或者安全要求(如線程安全) 不能夠使用共享技術的對象, 該對象一般不會出現在享元工廠中。

④、FlyweightFactory——享元工廠

職責非常簡單, 就是構造一個池容器, 同時提供從池中獲得對象的方法。

3、享元模式通用代碼

/**
 * 抽象享元角色
 */
public abstract class Flyweight {
    // 內部狀態
    private String instrinsic;

    // 外部狀態 通過 final 修改,防止修改
    protected final String extrinsic;

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

    // 定義業務操作
    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 {
    // 定義一個池容器
    private static HashMap< String,Flyweight > pool = new HashMap<  >();

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

4、通過享元設計文本編輯器

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

4.1 普通實現

通常設計是把每個文字看成一個單獨對象。

package com.itcoke.designpattern.flyweight.edittext;

/**
 * 單個文字對象
 */
public class Character {
    // 字符
    private char c;
    // 字體型號
    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);
    }
}
/**
 * 編輯器實現
 */
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);
    }
}

客戶端:

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 享元模式改寫

上面的問題很容易發現,每一個字符就會創建一個 Character 對象,如果是幾百萬個字符,那內存中就會存在幾百萬的對象,那怎么去節省這些內存呢?

其實,分析一下,對于字體的格式,通常不會有很多,于是我們可以把字體格式設置為享元,也就是上面說的可以共享的內部狀態。

內部狀態(共享):字體類型、大小、顏色

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

于是代碼改寫如下:

public class CharacterStyle {
    // 字體型號
    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 中應用

看下面這段代碼,打印結果是啥?

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); 
    }
}

圖片

為什么是這種結果呢?

首先說一下 Integer i = 59;底層執行了:Integer i = Integer.valueOf(59); 這是自動裝箱。

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

然后我們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() {}
    }

其實這就是我們前面說的享元對象的工廠類,緩存 -128 到 127 之間的整型值,這是最常用的一部分整型值,當然JDK 也提供了方法來讓我們可以自定義緩存的最大值。

6、享元模式優點

減少應用程序創建的對象, 降低程序內存的占用, 增強程序的性能。

但它同時也提高了系統復雜性, 需要分離出外部狀態和內部狀態, 而且外部狀態具有固化特性, 不應該隨內部狀態改變而改變, 否則導致系統的邏輯混亂。

7、享元模式應用場景

①、系統中存在大量的相似對象。

②、細粒度的對象都具備較接近的外部狀態, 而且內部狀態與環境無關, 也就是說對象沒有特定身份。

③、需要緩沖池的場景。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 內存
    +關注

    關注

    8

    文章

    3034

    瀏覽量

    74136
  • 代碼
    +關注

    關注

    30

    文章

    4801

    瀏覽量

    68735
  • 設計模式
    +關注

    關注

    0

    文章

    53

    瀏覽量

    8645
  • 線程
    +關注

    關注

    0

    文章

    505

    瀏覽量

    19705
收藏 人收藏

    評論

    相關推薦

    為了節省內存OLED不使用全緩沖模式了.

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

    windowsXP系統如何節省內存的方法

    windowsXP系統如何節省內存的方法  XP系統節省內存,加快開機速度的方法如下:1.禁用壓縮文件夾功能,2.減少開機磁盤掃描等待時間,重啟時候馬上你會看到效果。3.刪除系統備份文件,在各種
    發表于 02-26 15:40

    如何用PIC24FJ128GC010設置EEPROM

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

    分享一個MCU省內存的辦法

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

    分享一個MCU省內存的辦法

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

    單片機開發之節省內存大法

    提點一下,我一說估計很多人都清楚了,不過時間久了一些簡單的知識沒有去使用或者重溫,到了解決問題的時候還是容易卡殼,如果還沒有看過以前文章的可以到下面鏈接看看:?單片機開發之節省內存大法(...
    發表于 01-25 07:08

    ARM是怎樣使用多種低功耗模式節省功耗的

    三種電源模式 :運行、 睡眠、深度睡眠三種。一般而言,對于基于 ARM 架構的 MCU 在系統或者電源復位之后,CPU 處于運行狀態。當 CPU 不需要再繼續運行時,可以使用多種低功耗模式
    發表于 02-11 07:26

    iar build時出現內存不夠的問題

    單片機小白,語言是C,在用iar建工程的時候出現如圖錯誤,根據其他提問更改了優化等級仍未解決,請問還有其他解決方法嗎?或者有什么能優化代碼節省內存的算法舉例或者學習資料推薦?謝謝!
    發表于 03-26 21:49

    有沒有用tls省內存的方案啊

    上傳文件走tls加密,測下來整個流程最大會分配50K內存,這對于整個內存只有80多k的單片機簡直災難,有沒有用tls省內存的方案。
    發表于 09-30 10:07

    嵌入式系統節省內存的解決方法

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

    【MCU】一種單片機節省內存的方法(補充)

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

    單片機單口不可用或被占用_【MCU】一種單片機節省內存的方法

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

    Chrome將全面推出“節省內存”和“節省電量”模式

    這個功能就像手機的 “超級省電模式”,適用于筆記本電腦電池電量不足,開啟省電模式后,當設備電池電量達到 20% 時,Chrome 將通過限制后天活動和帶動畫 / 視頻的網站的視覺效果
    的頭像 發表于 12-12 14:44 ?909次閱讀

    如何使用Redis更節省內存?

    當你的業務應用在 Redis 中存儲數據很少時,你可能并不太關心內存資源的使用情況。但隨著業務的發展,你的業務存儲在 Redis 中的數據就會越來越多。
    的頭像 發表于 12-19 15:41 ?965次閱讀

    如何通過在汽車子系統中共享麥克風節省空間和BOM成本

    電子發燒友網站提供《如何通過在汽車子系統中共享麥克風節省空間和BOM成本.pdf》資料免費下載
    發表于 09-14 10:58 ?0次下載
    如何<b class='flag-5'>通過</b>在汽車子系統中共享麥克風<b class='flag-5'>來</b><b class='flag-5'>節省</b>空間和BOM成本
    主站蜘蛛池模板: seyeye在清在线| 国产精品久久人妻无码网站一区无 | 91精品国产品国语在线不卡| 国产女人毛片| 日本19禁啪啪吃奶大尺度| poronovideos动物狗猪| 快播性爱电影| 51久久夜色精品国产| 恋夜影院安卓免费列表uc| 91国在线视频| 欧美91精品久久久久网免费| fryee性欧美18 19| 日韩一区二区三区四区区区| JIZZ幻女大全| 葵司中文第一次大战黑人| 在线播放免费人成毛片视频| 国产亚洲精品黑人粗大精选| 亚洲国产日韩欧美在线a乱码 | 国产精品一区二区四区| 亚洲高清有码中文字| 久久视频在线视频观看精品15| 1区2区3区4区产品不卡码网站| 欧美残忍xxxx极端| 国产国产乱老熟视频网站| 亚洲日韩精品AV中文字幕| 麻豆国产自制在线观看| 7m凹凸国产刺激在线视频| 涩涩爱涩涩电影网站| 嫩草影院永久在线一二三四| 亚洲精品久久久久一区二区三| 久久99这里只有精品| 99这里有精品视频视频| 婷婷精品国产亚洲AV在线观看| 黄色天堂在线| gratis videos欧美最新| 天天爽夜夜爽夜夜爽| 美女被强奷到抽搐的动态图| 怪物高h粗暴无尽| 91嫩草国产在线观看免费| 午夜宅宅伦电影网| 蜜芽资源高清在线观看|