摘要:為了防止內(nèi)存抖動(dòng),所以可以使用對(duì)象池順利解決問(wèn)題。獲取矩陣對(duì)象獲取某個(gè)矩陣的歸還矩陣對(duì)象注意事項(xiàng)如果對(duì)象池為空,則對(duì)象池自己會(huì)一個(gè)返回。如果對(duì)象池內(nèi)有對(duì)象,則取一個(gè)已存在的返回。
目錄介紹
01.什么是對(duì)象池
02.glide哪里用到對(duì)象池
03.多條件key緩存bitmap
3.1 多條件key創(chuàng)建
3.2 key值的復(fù)用
04.glide對(duì)象池總結(jié)
05.學(xué)以致用對(duì)象池
5.1 使用場(chǎng)景
5.2 實(shí)現(xiàn)步驟
5.3 對(duì)象池使用
5.4 項(xiàng)目實(shí)踐分享
06.對(duì)象池的容量
好消息博客筆記大匯總【16年3月到至今】,包括Java基礎(chǔ)及深入知識(shí)點(diǎn),Android技術(shù)博客,Python學(xué)習(xí)筆記等等,還包括平時(shí)開(kāi)發(fā)中遇到的bug匯總,當(dāng)然也在工作之余收集了大量的面試題,長(zhǎng)期更新維護(hù)并且修正,持續(xù)完善……開(kāi)源的文件是markdown格式的!同時(shí)也開(kāi)源了生活博客,從12年起,積累共計(jì)N篇[近100萬(wàn)字,陸續(xù)搬到網(wǎng)上],轉(zhuǎn)載請(qǐng)注明出處,謝謝!
鏈接地址:https://github.com/yangchong2...
如果覺(jué)得好,可以star一下,謝謝!當(dāng)然也歡迎提出建議,萬(wàn)事起于忽微,量變引起質(zhì)變!
01.什么時(shí)對(duì)象池
對(duì)象池作用
在某些時(shí)候,我們需要頻繁使用一些臨時(shí)對(duì)象,如果每次使用的時(shí)候都申請(qǐng)新的資源,很有可能會(huì)引發(fā)頻繁的 gc 而影響應(yīng)用的流暢性。這個(gè)時(shí)候如果對(duì)象有明確的生命周期,那么就可以通過(guò)定義一個(gè)對(duì)象池來(lái)高效的完成復(fù)用對(duì)象。
對(duì)象池使用場(chǎng)景
glide中對(duì)加載圖片時(shí)頻繁創(chuàng)建對(duì)象使用到了對(duì)象池。
02.glide使用對(duì)象池
glide頻繁請(qǐng)求圖片
比如Glide中,每個(gè)圖片請(qǐng)求任務(wù),都需要用到類。若每次都需要重新new這些類,并不是很合適。而且在大量圖片請(qǐng)求時(shí),頻繁創(chuàng)建和銷毀這些類,可能會(huì)導(dǎo)致內(nèi)存抖動(dòng),影響性能。
Glide使用對(duì)象池的機(jī)制,對(duì)這種頻繁需要?jiǎng)?chuàng)建和銷毀的對(duì)象保存在一個(gè)對(duì)象池中。每次用到該對(duì)象時(shí),就取對(duì)象池空閑的對(duì)象,并對(duì)它進(jìn)行初始化操作,從而提高框架的性能。
03.多條件key緩存bitmap 3.1 多條件key創(chuàng)建
首先看一個(gè)簡(jiǎn)單的緩存bitmap代碼,代碼如下所示
就簡(jiǎn)單的通過(guò) HashMap 緩存了Bitmap資源,只有在緩存不存在時(shí)才會(huì)執(zhí)行加載這個(gè)耗時(shí)操作。但是上面的緩存條件十分簡(jiǎn)單,是通過(guò)圖片的名字決定的,這很大程度上滿足不了實(shí)際的需求。可能會(huì)出現(xiàn)意想不到的問(wèn)題……
private final Mapcache = new HashMap<>() private void setImage(ImageView iv, String name){ Bitmap b = cache.get(name); if(b == null){ b = loadBitmap(name); cache.put(name, b); } iv.setImageBitmap(b); }
多條件 Key
所以我們就需要定義一個(gè)Key對(duì)象來(lái)包含各種緩存的條件,例如我們除了圖片名字作為條件,還有圖片的寬度,高度也決定了是否是同一個(gè)資源,那么代碼將變成如下:
注意多條件key需要重寫equals和hashCode方法。equals注意是比較兩個(gè)對(duì)象是否相同,而hashCode主要作用是當(dāng)數(shù)據(jù)量很大的時(shí)候,使用equals一一比較比較會(huì)大大降低效率。hashcode實(shí)際上是返回對(duì)象的存儲(chǔ)地址,如果這個(gè)位置上沒(méi)有元素,就把元素直接存儲(chǔ)在上面,如果這個(gè)位置上已經(jīng)存在元素,這個(gè)時(shí)候才去調(diào)用equal方法與新元素進(jìn)行比較就可以提高效率呢!
private final Map3.2 key值的復(fù)用cache = new HashMap<>(); private void setImage(ImageView iv, String name, int width, int height){ Key key = new Key(name, width, height); Bitmap b = cache.get(key); if(b == null){ b = loadBitmap(name, width, height); cache.put(key, b); } iv.setImageBitmap(b); } public class Key { private final String name; private final int width; private final int heifht; public Key(String name, int width, int heifht) { this.name = name; this.width = width; this.heifht = heifht; } public String getName() { return name; } public int getWidth() { return width; } public int getHeifht() { return heifht; } @Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } Key key = (Key) o; if (width != key.width) { return false; } if (heifht != key.heifht) { return false; } return name != null ? name.equals(key.name) : key.name == null; } @Override public int hashCode() { int result = name != null ? name.hashCode() : 0; final int prime = 31; result = prime * result + width; result = prime * result + heifht; return result; } }
key值的復(fù)用是如何操作的
雖然可以支持多條件的緩存鍵值了,但是每次查找緩存前都需要?jiǎng)?chuàng)建一個(gè)新的 Key 對(duì)象,雖然這個(gè) Key 對(duì)象很輕量,但是終歸覺(jué)得不優(yōu)雅。gilde源碼中會(huì)提供一個(gè) BitmapPool 來(lái)獲取 Bitmap 以避免 Bitmap 的頻繁申請(qǐng)。而 BitmapPool 中 get 方法的簽名是這樣的:
Bitmap 需要同時(shí)滿足三個(gè)條件(高度、寬度、顏色編碼)都相同時(shí)才能算是同一個(gè) Bitmap,那么內(nèi)部是如何進(jìn)行查找的呢?需要知道的是,BitmapPool 只是一個(gè)接口,內(nèi)部的默認(rèn)實(shí)現(xiàn)是 LruBitmapPool
看LruBitmapPool中g(shù)et方法
注意重點(diǎn)看這行代碼:final Bitmap result = strategy.get(width, height, config != null ? config : DEFAULT_CONFIG);
strategy 是 LruPoolStrategy 接口類型,查看其中一個(gè)繼承該接口類的 get 方法的實(shí)現(xiàn)
@Override @NonNull public Bitmap get(int width, int height, Bitmap.Config config) { Bitmap result = getDirtyOrNull(width, height, config); if (result != null) { // Bitmaps in the pool contain random data that in some cases must be cleared for an image // to be rendered correctly. we shouldn"t force all consumers to independently erase the // contents individually, so we do so here. See issue #131. result.eraseColor(Color.TRANSPARENT); } else { result = createBitmap(width, height, config); } return result; } @Nullable private synchronized Bitmap getDirtyOrNull( int width, int height, @Nullable Bitmap.Config config) { assertNotHardwareConfig(config); // 對(duì)于非公共配置類型,配置為NULL,這可能導(dǎo)致轉(zhuǎn)換以此處請(qǐng)求的配置方式天真地傳入NULL。 final Bitmap result = strategy.get(width, height, config != null ? config : DEFAULT_CONFIG); if (result == null) { if (Log.isLoggable(TAG, Log.DEBUG)) { Log.d(TAG, "Missing bitmap=" + strategy.logBitmap(width, height, config)); } misses++; } else { hits++; currentSize -= strategy.getSize(result); tracker.remove(result); normalize(result); } if (Log.isLoggable(TAG, Log.VERBOSE)) { Log.v(TAG, "Get bitmap=" + strategy.logBitmap(width, height, config)); } dump(); return result; }
然后看一下SizeConfigStrategy類中的get方法
看一下下面注釋的兩行重點(diǎn)代碼。同樣也需要一個(gè)專門的類型用來(lái)描述鍵,但是鍵result居然是也是從一個(gè)對(duì)象池keyPool中獲取的。
可以看到 Key 是一個(gè)可變對(duì)象,每次先獲取一個(gè)Key對(duì)象(可能是池中的,也可能是新創(chuàng)建的),然后把變量初始化。但是大家知道,HashMap 中的 Key 不應(yīng)該是可變對(duì)象,因?yàn)槿绻?Key的 hashCode 發(fā)生變化將會(huì)導(dǎo)致查找失效,那么這里是如何做到 Key 是可變對(duì)象的同時(shí)保證能正確的作為 HashMap 中的鍵使用呢?
@Override @Nullable public Bitmap get(int width, int height, Bitmap.Config config) { int size = Util.getBitmapByteSize(width, height, config); Key bestKey = findBestKey(size, config); //第一處代碼 Bitmap result = groupedMap.get(bestKey); if (result != null) { decrementBitmapOfSize(bestKey.size, result); result.reconfigure(width, height, result.getConfig() != null ? result.getConfig() : Bitmap.Config.ARGB_8888); } return result; } private Key findBestKey(int size, Bitmap.Config config) { //第二處代碼 Key result = keyPool.get(size, config); for (Bitmap.Config possibleConfig : getInConfigs(config)) { NavigableMapsizesForPossibleConfig = getSizesForConfig(possibleConfig); Integer possibleSize = sizesForPossibleConfig.ceilingKey(size); if (possibleSize != null && possibleSize <= size * MAX_SIZE_MULTIPLE) { if (possibleSize != size || (possibleConfig == null ? config != null : !possibleConfig.equals(config))) { keyPool.offer(result); result = keyPool.get(possibleSize, possibleConfig); } break; } } return result; } @VisibleForTesting static class KeyPool extends BaseKeyPool { Key get(int width, int height, Bitmap.Config config) { Key result = get(); result.init(width, height, config); return result; } @Override protected Key create() { return new Key(this); } }
然后看一下groupedMap的代碼
在查找時(shí),如果沒(méi)有發(fā)現(xiàn)命中的值,那么就會(huì)創(chuàng)建新的值,并將其連同 Key 保存在 HashMap 中,不會(huì)對(duì) Key 進(jìn)行復(fù)用。而如果發(fā)現(xiàn)了命中的值,也就是說(shuō) HashMap 中已經(jīng)有一個(gè)和當(dāng)前 Key 相同的 Key 對(duì)象了,那么 Key 就可以通過(guò) offer 方法回收到了 KeyPool 中,以待下一次查找時(shí)復(fù)用。
@Nullable public V get(K key) { LinkedEntry04.glide對(duì)象池總結(jié)entry = keyToEntry.get(key); if (entry == null) { entry = new LinkedEntry<>(key); keyToEntry.put(key, entry); } else { key.offer(); } makeHead(entry); return entry.removeLast(); }
優(yōu)化點(diǎn)
對(duì)開(kāi)銷較大的 Bitmap 進(jìn)行了復(fù)用,就連為了復(fù)用Bitmap時(shí)重復(fù)申請(qǐng)的Key對(duì)象都進(jìn)行了復(fù)用,盡可能的減少了對(duì)象的創(chuàng)建開(kāi)銷,保證了應(yīng)用的流暢性。
為何要多條件key
針對(duì)bitmap,加載圖片特別頻繁且多,不建議只是簡(jiǎn)單通過(guò)一個(gè)name圖片名稱作為鍵,因?yàn)榭赡軋D片名稱是一樣的,比如有時(shí)候接口返回同樣名稱的圖片有大圖,正常圖,縮略圖等,那樣可能會(huì)存儲(chǔ)重復(fù)或者碰撞。但是通過(guò)name,還有圖片寬高字段,就可以大大減小這種問(wèn)題呢。
HashMap中鍵存儲(chǔ)問(wèn)題
為了正確使用HashMap,選擇恰當(dāng)?shù)腒ey是非常重要的。Key在HashMap里是不可重復(fù)的。也就是說(shuō)這個(gè)key對(duì)象的hashcode是不能改變的。那么多條件key是如何保證唯一了,如果要以可變對(duì)象作為key的話,那就必須要重寫hashcode和equals方法來(lái)達(dá)到這個(gè)目的,除此之外,別無(wú)他法。同時(shí)這個(gè)時(shí)候可以利用keyPool對(duì)key對(duì)象進(jìn)行緩存。
那么有人會(huì)問(wèn),要是key值變化了,怎么辦?如果HashMap的Key的哈希值在存儲(chǔ)鍵值對(duì)后發(fā)生改變,Map可能再也查找不到這個(gè)Entry了。如果Key對(duì)象是可變的,那么Key的哈希值就可能改變。在HashMap中可變對(duì)象作為Key會(huì)造成數(shù)據(jù)丟失。這也就是為何key一般要用string或者int值的緣由呢。
05.學(xué)以致用對(duì)象池 5.1 使用場(chǎng)景在寫圖片縮放控件的時(shí)候,當(dāng)雙手指滑動(dòng)時(shí),會(huì)頻繁操作讓圖片縮放和移動(dòng)。這就會(huì)頻繁用到變化矩陣Matrix,還有RectF繪畫相關(guān)的工具類。為了防止內(nèi)存抖動(dòng),所以可以使用對(duì)象池順利解決問(wèn)題。
內(nèi)存抖動(dòng)是由于在短時(shí)間內(nèi)有大量的對(duì)象被創(chuàng)建或者被回收的現(xiàn)象,內(nèi)存抖動(dòng)出現(xiàn)原因主要是頻繁(很重要)在循環(huán)里創(chuàng)建對(duì)象(導(dǎo)致大量對(duì)象在短時(shí)間內(nèi)被創(chuàng)建,由于新對(duì)象是要占用內(nèi)存空間的而且是頻繁,如果一次或者兩次在循環(huán)里創(chuàng)建對(duì)象對(duì)內(nèi)存影響不大,不會(huì)造成嚴(yán)重內(nèi)存抖動(dòng)這樣可以接受也不可避免,頻繁的話就很內(nèi)存抖動(dòng)很嚴(yán)重),它伴隨著頻繁的GC。而我們知道GC太頻繁會(huì)大量占用ui線程和cpu資源,會(huì)導(dǎo)致app整體卡頓。
5.2 實(shí)現(xiàn)步驟
創(chuàng)建抽象ObjectsPool類,由于緩存的對(duì)象可能是不同的類型,這里使用泛型T。主要操作是從對(duì)象池請(qǐng)求對(duì)象的函數(shù),還有釋放對(duì)象回對(duì)象池的函數(shù)。同時(shí)可以自己設(shè)置對(duì)象池的大小,可以使用隊(duì)列來(lái)實(shí)現(xiàn)存儲(chǔ)功能。
代碼如下:
/** ** @author yangchong * blog : https://github.com/yangchong211 * time : 2017/05/30 * desc : 對(duì)象池抽象類 * revise: 具體使用方法請(qǐng)看:https://github.com/yangchong211/YCGallery **/ public abstract class ObjectsPool{ /* * 防止頻繁new對(duì)象產(chǎn)生內(nèi)存抖動(dòng). * 由于對(duì)象池最大長(zhǎng)度限制,如果吞度量超過(guò)對(duì)象池容量,仍然會(huì)發(fā)生抖動(dòng). * 此時(shí)需要增大對(duì)象池容量,但是會(huì)占用更多內(nèi)存. * 對(duì)象池容納的對(duì)象類型 */ /** * 對(duì)象池的最大容量 */ private int mSize; /** * 對(duì)象池隊(duì)列 */ private Queue mQueue; /** * 創(chuàng)建一個(gè)對(duì)象池 * * @param size 對(duì)象池最大容量 */ public ObjectsPool(int size) { mSize = size; mQueue = new LinkedList<>(); } /** * 獲取一個(gè)空閑的對(duì)象 * * 如果對(duì)象池為空,則對(duì)象池自己會(huì)new一個(gè)返回. * 如果對(duì)象池內(nèi)有對(duì)象,則取一個(gè)已存在的返回. * take出來(lái)的對(duì)象用完要記得調(diào)用given歸還. * 如果不歸還,讓然會(huì)發(fā)生內(nèi)存抖動(dòng),但不會(huì)引起泄漏. * * @return 可用的對(duì)象 * * @see #given(Object) */ public T take() { //如果池內(nèi)為空就創(chuàng)建一個(gè) if (mQueue.size() == 0) { return newInstance(); } else { //對(duì)象池里有就從頂端拿出來(lái)一個(gè)返回 return resetInstance(mQueue.poll()); } } /** * 歸還對(duì)象池內(nèi)申請(qǐng)的對(duì)象 * 如果歸還的對(duì)象數(shù)量超過(guò)對(duì)象池容量,那么歸還的對(duì)象就會(huì)被丟棄 * * @param obj 歸還的對(duì)象 * * @see #take() */ public void given(T obj) { //如果對(duì)象池還有空位子就歸還對(duì)象 if (obj != null && mQueue.size() < mSize) { mQueue.offer(obj); } } /** * 實(shí)例化對(duì)象 * * @return 創(chuàng)建的對(duì)象 */ abstract protected T newInstance(); /** * 重置對(duì)象 * * 把對(duì)象數(shù)據(jù)清空到就像剛創(chuàng)建的一樣. * * @param obj 需要被重置的對(duì)象 * @return 被重置之后的對(duì)象 */ abstract protected T resetInstance(T obj); }
然后,可以定義一個(gè)矩陣對(duì)象池,需要實(shí)現(xiàn)上面的抽象方法。如下所示
public class MatrixPool extends ObjectsPool{ /**
*/ public MatrixPool(int size) { super(size); } @Override protected Matrix newInstance() { return new Matrix(); } @Override protected Matrix resetInstance(Matrix obj) { obj.reset(); return obj; } } ```5.3 對(duì)象池使用
至于使用,一般是獲取矩陣對(duì)象,還有歸還矩陣對(duì)象。
/**
*/ private static MatrixPool mMatrixPool = new MatrixPool(16); /** * 獲取矩陣對(duì)象 */ public static Matrix matrixTake() { return mMatrixPool.take(); } /** * 獲取某個(gè)矩陣的copy */ public static Matrix matrixTake(Matrix matrix) { Matrix result = mMatrixPool.take(); if (matrix != null) { result.set(matrix); } return result; } /** * 歸還矩陣對(duì)象 */ public static void matrixGiven(Matrix matrix) { mMatrixPool.given(matrix); } ```
注意事項(xiàng)
如果對(duì)象池為空,則對(duì)象池自己會(huì)new一個(gè)返回。如果對(duì)象池內(nèi)有對(duì)象,則取一個(gè)已存在的返回。take出來(lái)的對(duì)象用完要記得調(diào)用given歸還,如果不歸還,仍然會(huì)發(fā)生內(nèi)存抖動(dòng),但不會(huì)引起泄漏。
5.4 項(xiàng)目實(shí)踐分享
避免發(fā)生內(nèi)存抖動(dòng)的幾點(diǎn)建議:
盡量避免在循環(huán)體內(nèi)創(chuàng)建對(duì)象,應(yīng)該把對(duì)象創(chuàng)建移到循環(huán)體外。
注意自定義View的onDraw()方法會(huì)被頻繁調(diào)用,所以在這里面不應(yīng)該頻繁的創(chuàng)建對(duì)象。
當(dāng)需要大量使用Bitmap的時(shí)候,試著把它們緩存在數(shù)組中實(shí)現(xiàn)復(fù)用。
對(duì)于能夠復(fù)用的對(duì)象,同理可以使用對(duì)象池將它們緩存起來(lái)。
大多數(shù)對(duì)象的復(fù)用,最終實(shí)施的方案都是利用對(duì)象池技術(shù),要么是在編寫代碼的時(shí)候顯式的在程序里面去創(chuàng)建對(duì)象池,然后處理好復(fù)用的實(shí)現(xiàn)邏輯,要么就是利用系統(tǒng)框架既有的某些復(fù)用特性達(dá)到減少對(duì)象的重復(fù)創(chuàng)建,從而減少內(nèi)存的分配與回收。
圖片縮放案例:https://github.com/yangchong2...
06.對(duì)象池的容量
通常情況下,我們需要控制對(duì)象池的大小
如果對(duì)象池沒(méi)有限制,可能導(dǎo)致對(duì)象池持有過(guò)多的閑置對(duì)象,增加內(nèi)存的占用
如果對(duì)象池閑置過(guò)小,沒(méi)有可用的對(duì)象時(shí),會(huì)造成之前對(duì)象池?zé)o可用的對(duì)象時(shí),再次請(qǐng)求出現(xiàn)的問(wèn)題
對(duì)象池的大小選取應(yīng)該結(jié)合具體的使用場(chǎng)景,結(jié)合數(shù)據(jù)(觸發(fā)池中無(wú)可用對(duì)象的頻率)分析來(lái)確定。
使用對(duì)象池也是要有一定代價(jià)的:短時(shí)間內(nèi)生成了大量的對(duì)象占滿了池子,那么后續(xù)的對(duì)象是不能復(fù)用的。
其他介紹 01.關(guān)于博客匯總鏈接1.技術(shù)博客匯總
2.開(kāi)源項(xiàng)目匯總
3.生活博客匯總
4.喜馬拉雅音頻匯總
5.其他匯總
02.關(guān)于我的博客我的個(gè)人站點(diǎn):www.yczbj.org,www.ycbjie.cn
github:https://github.com/yangchong211
知乎:https://www.zhihu.com/people/...
簡(jiǎn)書:http://www.jianshu.com/u/b7b2...
csdn:http://my.csdn.net/m0_37700275
喜馬拉雅聽(tīng)書:http://www.ximalaya.com/zhubo...
開(kāi)源中國(guó):https://my.oschina.net/zbj161...
泡在網(wǎng)上的日子:http://www.jcodecraeer.com/me...
郵箱:yangchong211@163.com
阿里云博客:https://yq.aliyun.com/users/a... 239.headeruserinfo.3.dT4bcV
segmentfault頭條:https://segmentfault.com/u/xi...
掘金:https://juejin.im/user/593943...
03.參考博客https://www.jianshu.com/p/b74...
對(duì)象池優(yōu)化綜合案例:https://github.com/yangchong2... 對(duì)象池優(yōu)化縮放圖片案例:https://github.com/yangchong2...文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/77520.html
摘要:如果為負(fù)值,表示不運(yùn)行檢測(cè)線程。默認(rèn)為策略的類名,默認(rèn)為這里就用到了上面提到的兩個(gè)參數(shù)對(duì)象池原理分析避免泄漏配置參數(shù)詳解,以及資源回收,從池中獲取資源,將資源返還給池邏輯解析 序 本文主要解析一下apache common pools下的GenericObjectPool的參數(shù)設(shè)置 GenericObjectPool commons-pool2-2.4.2-sources.jar!/o...
摘要:當(dāng)一個(gè)進(jìn)行需要處理阻塞操作時(shí),它會(huì)將這個(gè)任務(wù)交給線程池來(lái)完成。線程池配置如果你確信引入線程池對(duì)性能提升有效,那么咱們可以繼續(xù)了解一些調(diào)優(yōu)參數(shù)。這個(gè)錯(cuò)誤表示這個(gè)線程池消費(fèi)小于生產(chǎn),所以可以增加隊(duì)列長(zhǎng)度,如果調(diào)整無(wú)效,說(shuō)明系統(tǒng)達(dá)到了瓶頸。 五年級(jí)英語(yǔ)水平,端午家庭作業(yè)。 前言 Nginx以異步、事件驅(qū)動(dòng)的方式處理連接。傳統(tǒng)的方式是每個(gè)請(qǐng)求新起一個(gè)進(jìn)程或線程,Nginx沒(méi)這樣做,它通過(guò)非...
摘要:錯(cuò)誤使用單利在開(kāi)發(fā)中單例經(jīng)常需要持有對(duì)象,如果持有的對(duì)象生命周期與單例生命周期更短時(shí),或?qū)е聼o(wú)法被釋放回收,則有可能造成內(nèi)存泄漏。如果集合是類型的話,那內(nèi)存泄漏情況就會(huì)更為嚴(yán)重。 目錄介紹 1.OOM和崩潰優(yōu)化 1.1 OOM優(yōu)化 1.2 ANR優(yōu)化 1.3 Crash優(yōu)化 2.內(nèi)存泄漏優(yōu)化 2.0 動(dòng)畫資源未釋放 2.1 錯(cuò)誤使用單利 2.2 錯(cuò)誤使用靜態(tài)變量 2.3 ...
摘要:會(huì)展示這個(gè)節(jié)點(diǎn)目前正在服務(wù)中的段的數(shù)量。線程池部分在內(nèi)部維護(hù)了線程池。這些線程池相互協(xié)作完成任務(wù),有必要的話相互間還會(huì)傳遞任務(wù)。每個(gè)線程池會(huì)列出已配置的線程數(shù)量,當(dāng)前在處理任務(wù)的線程數(shù)量,以及在隊(duì)列中等待處理的任務(wù)單元數(shù)量。 showImg(https://segmentfault.com/img/remote/1460000011618283?w=1920&h=1080); 集群健康...
閱讀 2295·2021-11-24 09:39
閱讀 2874·2021-07-29 13:49
閱讀 2404·2019-08-29 14:15
閱讀 2306·2019-08-29 12:40
閱讀 3366·2019-08-26 13:42
閱讀 699·2019-08-26 12:13
閱讀 2126·2019-08-26 11:41
閱讀 3412·2019-08-23 18:32