Lifecycle 使用与源码分析——彻底搞懂Lifecycle原理
一、Lifecycle 介绍
Lifecycle是一个生命周期感知组件,一般用来响应Activity、Fragment等组件的生命周期变化,并将变化通知到已注册的观察者。有助于更好地组织代码,让代码逻辑符合生命周期规范,减少内存泄漏,增强稳定性。
这些组件可帮助您生成更易于组织且通常更轻量级的代码,这些代码更易于维护。
二、使用方法
先来看一下如何使用,这样再去分析源码就能有的放矢,
1.添加依赖:
在app或者module目录下的build.gradle中,添加依赖:
这里介绍Androidx 项目引入lifecycle
dependencies {implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.2.0"// Annotation processorkapt "androidx.lifecycle:lifecycle-compiler:2.2.0"
}
2.LifecycleObserver接口
实现LifecycleObserver 接口,使用 @OnLifecycleEvent注解在方法上,注解值表示该方法对应生命周期的哪个函数
官方建议Java 8 中,实现DefaultLifecycleObserver 接口,并实现其中的方法。但是在2.2.0 并没有找到这个接口,并且FullLifecycleObserver也被限制为包权限
//特别注意,这里不需要传入Lifecycle,本例是为了测试嵌套添加LifecycleObserver 的生命周期,才故意这样写
class P1(var mLifecycle: Lifecycle) : LifecycleObserver {@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)fun p1Create() {Log.i("P1 ", "执行了p1 的 create 生命周期")}@OnLifecycleEvent(Lifecycle.Event.ON_START)fun p1Start() {//注意,这里是嵌套添加LifecycleObserver,//会在P1 Start 阶段完全执行完,才去执行P2 Start阶段mLifecycle.addObserver(P2(mLifecycle))Log.i("P1 ", "执行了p1 的 start 生命周期")}@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)fun p1Resume() {Log.i("P1 ", "执行了p1 的 resume 生命周期")}@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)fun p1Pause() {Log.i("P1 ", "执行了p1 的 pause 生命周期")}
}
3.将LifecycleObserver添加到Lifecycle的观察者列表
如果你使用新版本的AppcompatActivity(>26.1.0),因为 AppCompatActivity 实现了 LifecycleOwner接口,所以可以这么写:
class MainActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)Log.i("MainActivity ", "onCreate 生命周期 开始执行")setContentView(R.layout.activity_main)lifecycle.addObserver(P1(lifecycle))Log.i("MainActivity ", "onCreate 生命周期 执行完成")}override fun onStart() {super.onStart()Log.i("MainActivity ", "start 生命周期 执行完成")}
}
输出日志
2020-08-17 14:23:34.604 8833-8833/com.example.myapplication I/MainActivity: onCreate 生命周期 开始执行
2020-08-17 14:23:34.856 8833-8833/com.example.myapplication I/MainActivity: onCreate 生命周期 执行完成
2020-08-17 14:23:35.946 8833-8833/com.example.myapplication I/P1: 执行了p1 的 create 生命周期
2020-08-17 14:23:36.454 8833-8833/com.example.myapplication I/MainActivity: start 生命周期 执行完成
2020-08-17 14:23:37.366 8833-8833/com.example.myapplication I/P2: 执行了p2 的 create 生命周期
2020-08-17 14:23:37.482 8833-8833/com.example.myapplication I/P1: 执行了p1 的 start 生命周期
2020-08-17 14:23:37.668 8833-8833/com.example.myapplication I/P2: 执行了P2 的 start 生命周期
2020-08-17 14:23:38.377 8833-8833/com.example.myapplication I/P1: 执行了p1 的 resume 生命周期
2020-08-17 14:23:38.544 8833-8833/com.example.myapplication I/P2: 执行了p2 的 resume 生命周期
当然也可以自己实现 LifecycleOwner接口,需要做3件事情
1、实现LifecycleOwner 接口的方法:getLifecycle()
2、注册Lifecycle new LifecycleRegistry(this)
3、在Activity生命周期函数中分发事件
public class MainActivity extends Activity implements LifecycleOwner {private LifecycleRegistry mLifecycleRegistry;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mLifecycleRegistry = new LifecycleRegistry(this);mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);mLifecycleRegistry.addObserver(new TestObserver());}@NonNull@Overridepublic Lifecycle getLifecycle() {return mLifecycleRegistry;}@Overridepublic void onStart() {super.onStart();mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);}@Overridepublic void onResume() {super.onResume();mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME);}@Overridepublic void onPause() {mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE);super.onPause();}@Overridepublic void onStop() {mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP);super.onStop();}@Overridepublic void onDestroy() {mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY);super.onDestroy();}
}
三、源码分析
3.1 Lifecycle相关的类图
先来看一下 Lifecycle相关的类图
自定义的Activity都继承自AppCompatActivity ,AppCompatActivity 实现了LifecycleOwner接口,同时持有实现了Lifecycle的LifecycleRegistry对象,这个对象就可以将其理解为观察者模式中的Subject,LifecycleRegistr聚合多个LifecycleObserver,生命周期改变时通知LifecycleObserver进行相应的方法调用。
3.2、生命周期感知
Lifecycle是一个生命周期感知的框架,那么它是如何感知Activity的生命周期呢?
看AppCompatActivity 继承的ComponentActivity 中的onCretae方法
protected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);ReportFragment.injectIfNeededIn(this);}
ReportFragment 类是一个Fragment,它负责分派生命周期的时间.
injectIfNeededIn()
就是在当前的Activity里添加一个ReportFragment。
public static void injectIfNeededIn(Activity activity) {// ProcessLifecycleOwner should always correctly work and some activities may not extend// FragmentActivity from support lib, so we use framework fragments for activitiesandroid.app.FragmentManager manager = activity.getFragmentManager();if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) {manager.beginTransaction().add(new ReportFragment(), REPORT_FRAGMENT_TAG).commit();// Hopefully, we are the first to make a transaction.manager.executePendingTransactions();}}
再看ReportFragment的生命周期函数。
@Overridepublic void onActivityCreated(Bundle savedInstanceState) {super.onActivityCreated(savedInstanceState);dispatchCreate(mProcessListener);dispatch(Lifecycle.Event.ON_CREATE);}@Overridepublic void onStart() {super.onStart();dispatchStart(mProcessListener);dispatch(Lifecycle.Event.ON_START);}@Overridepublic void onResume() {super.onResume();dispatchResume(mProcessListener);dispatch(Lifecycle.Event.ON_RESUME);}@Overridepublic void onPause() {super.onPause();dispatch(Lifecycle.Event.ON_PAUSE);}@Overridepublic void onStop() {super.onStop();dispatch(Lifecycle.Event.ON_STOP);}@Overridepublic void onDestroy() {super.onDestroy();dispatch(Lifecycle.Event.ON_DESTROY);// just want to be sure that we won't leak reference to an activitymProcessListener = null;}private void dispatch(Lifecycle.Event event) {Activity activity = getActivity();if (activity instanceof LifecycleRegistryOwner) {((LifecycleRegistryOwner) activity).getLifecycle().handleLifecycleEvent(event);return;}if (activity instanceof LifecycleOwner) {Lifecycle lifecycle = ((LifecycleOwner) activity).getLifecycle();if (lifecycle instanceof LifecycleRegistry) {((LifecycleRegistry) lifecycle).handleLifecycleEvent(event);}}}
你会发现都调用了dispatch()
方法,而dispatch()
方法则会判断Activity是否实现了LifecycleOwner接口,如果实现了该接口就调用LifecycleRegister的handleLifecycleEvent()
,这样生命周期的状态就会借由LifecycleRegistry通知给各个LifecycleObserver从而调用其中对应Lifecycle.Event的方法。这种通过Fragment来感知Activity生命周期的方法其实在Glide的中也是有体现的。
这是Activity的声明周期感知,那么Fragment呢?看一下Fragment源码你会发现Fragment也实现了LifecycleOwner接口,也关联了一个LifecycleRegistry对象
3.3、LifecycleRegister分析
把LifecycleObserver (观察者)添加到 Lifecycle(被观察者)的列表中,使用的是addObserver,而在源代码中,实现Lifecycle接口的是LifecycleRegister
getLifecycle().addObserver(new LifecycleObserver1 ());
LifecycleRegister#addObserver()
来看一下LifecycleRegister 类中的addObserver方法
@Overridepublic void addObserver(@NonNull LifecycleObserver observer) {//这个状态值是一个枚举类型的,生命周期越靠后,值越小 DESTROYED < INITIALIZED < CREATED < STARTED < RESUMEDState initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);if (previous != null) {return;}//由上面的使用可知,LifecycleOwner相当于是观察者模式中的被观察者,它来向各LifecycleObserver发送生命周期消息LifecycleOwner lifecycleOwner = mLifecycleOwner.get();if (lifecycleOwner == null) {// it is null we should be destroyed. Fallback quicklyreturn;}//mAddingObserverCounter 表示正在添加的观察者的数量,//开始添加新的observe之前,对该变量进行 ++ 操作,添加完成后,进行 -- 操作。//如果mAddingObserverCounter 不为0 ,说明在添加observe A 时,在while循环中更新observe A 的生命周期时,又添加了新的observe B。//这就是嵌套事件。而由于B 是后添加的,所以同一生命周期的回调顺序,要保证B 在A后 被回调。//mHandlingEvent 表示是否正在处理事件中boolean isReentrance = mAddingObserverCounter != 0 || mHandlingEvent;State targetState = calculateTargetState(observer);mAddingObserverCounter++;//这里是while 循环,新添加的LifecycleObserver ,会不断更新自己的生命周期到指定的targetStatewhile ((statefulObserver.mState.compareTo(targetState) < 0&& mObserverMap.contains(observer))) {//为了 嵌套添加observer,保证各observe的回调顺序,这个状态是保存在变量mParentStates中的pushParentState(statefulObserver.mState);//注意这里的upEvent,获取statefulObserver.mState下一状态的值,//也就是说mParentStates中的状态 比 即将执行的生命周期 要晚一个阶段statefulObserver.dispatchEvent(lifecycleOwner, upEvent(statefulObserver.mState));popParentState();// mState / subling may have been changed recalculatetargetState = calculateTargetState(observer);}// 没有事件正在处理,或者是添加了observe,就需要重新同步一次状态// 嵌套添加observer,只有最先添加的observer,isReentrance 才是false,才会执行sync()// 也就是说嵌套添加observer,sync 只会被执行一次。if (!isReentrance) {// we do sync only on the top level.//防止在添加过程中,生命周期发生了变化,状态不一致的问题sync();}mAddingObserverCounter--;}
LifecycleRegister#FastSafeIterableMap
其中mObserverMap 是FastSafeIterableMap
private FastSafeIterableMap<LifecycleObserver, ObserverWithState> mObserverMap = new FastSafeIterableMap<>();
这里生成了一个ObserverWithState,然后放入FastSafeIterableMap里,这个类
是一个自定义列表,用于保存观察者并可在遍历期间处理删除/添加。
观察者1和观察者2的任何时刻:如果addition_order(observer1)<addition_order(observer2),那么 state(observer1)> = state(observer2)
LifecycleRegister#calculateTargetState
该函数只在addObserver 中被调用,看上去简单,但是暗藏玄机,理解了变量mParentStates ,才算理解
private State calculateTargetState(LifecycleObserver observer) {//前面observer 都会被添加到一个Map中, 这里是在map中获取到当前observer的前一个observerEntry<LifecycleObserver, ObserverWithState> previous = mObserverMap.ceil(observer);// 获取前一个observer 的最终状态State siblingState = previous != null ? previous.getValue().mState : null;// 如果是嵌套添加observer,获取父级observer的状态,这个状态是当前父级状态的前一个状态(详见addObserver 的while循环中的代码),State parentState = !mParentStates.isEmpty() ? mParentStates.get(mParentStates.size() - 1): null;//获取最小状态,DESTROYED < INITIALIZED < CREATED < STARTED < RESUMED return min(min(mState, siblingState), parentState);}
有小伙伴可能有疑问,已经有了siblingState状态,为什么还要获取parentState 状态? 而且如果你调试过程序会发现,这里的siblingState 值(如果有的话) 和parentState 值是一样的。
parentState的存在是为了解决下面这种情况,结合下面这个
void onStart() {mRegistry.removeObserver(this);mRegistry.add(newObserver);}
为了方便描述,我们把被删除的LifecycleObserver 称为 A,新添加的称为B
删除LifecycleObserver,也就是从mObserverMap中移除,那么在calculateTargetState 函数中,siblingState 的值就是null
这里是嵌套添加LifecycleObserverB,是在LifecycleObserverA的回调函数中添加的,此时LifecycleObserverA, 在源码中执行了pushParentState ,再回调本函数onStart,回调执行结束会执行popParentState。
如果此时添加LifecycleObserverB,在调用calculateTargetState函数中,siblingState 的值就可能为空的(如果mObserverMap 只有一个值,removeObserver后,就为空),parentState值不为空(在popParentState 中设置的,该值也就是LifecycleObserverA的上个生命阶段),最后添加完成后,执行了sync(),再次同步状态
也就说LifecycleObserverA 某一生命周期阶段(这里指onStart)执行完成后,才会执行LifecycleObserverB的同一生命周期阶段
LifecycleRegister#handleLifecycleEvent
前面提到了,每当生命周期发生变化,最终都会调用dispatch方法中的handleLifecycleEvent
方法
下图是每个生命周期对应的状态,及转换:
下面来看下handleLifecycleEvent
方法的代码:
public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {State next = getStateAfter(event);moveToState(next);}
private void moveToState(State next) {if (mState == next) {return;}mState = next;//mHandlingEvent 表示处理事件,所以不需要再次调用//mAddingObserverCounter != 0 表示正在添加observer(在函数addObserver),满足此条件,最后会调用sync(),所以这里不需再次调用if (mHandlingEvent || mAddingObserverCounter != 0) {// 停止正在更新生命周期的操作,因为有新的事件传递进来mNewEventOccurred = true;// we will figure out what to do on upper level.return;}mHandlingEvent = true;sync();mHandlingEvent = false;}
private void sync() {LifecycleOwner lifecycleOwner = mLifecycleOwner.get();if (lifecycleOwner == null) {Log.w(LOG_TAG, "LifecycleOwner is garbage collected, you shouldn't try dispatch "+ "new events from it.");return;}while (!isSynced()) {mNewEventOccurred = false;// no need to check eldest for nullability, because isSynced does it for us.if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) {backwardPass(lifecycleOwner);}Entry<LifecycleObserver, ObserverWithState> newest = mObserverMap.newest();if (!mNewEventOccurred && newest != null&& mState.compareTo(newest.getValue().mState) > 0) {forwardPass(lifecycleOwner);}}mNewEventOccurred = false;}
这里可以看到
- 如果ObserverWithState的state小于当前state,那么就调用forwardPass方法,
- 如果大于当前state,那么就调用backwardPass方法。
ObserverWithState默认的State是在addObserver方法里确定的,如果不是DESTROYED状态,就初始为 INITIALIZED
LifecycleRegister#forwardPass
继续看forwardPass方法
private void forwardPass(LifecycleOwner lifecycleOwner) {Iterator<Entry<LifecycleObserver, ObserverWithState>> ascendingIterator =mObserverMap.iteratorWithAdditions();//如果有新的事件发生,则停止 while (ascendingIterator.hasNext() && !mNewEventOccurred) {Entry<LifecycleObserver, ObserverWithState> entry = ascendingIterator.next();ObserverWithState observer = entry.getValue();//如果有新的事件发生,则停止 while ((observer.mState.compareTo(mState) < 0 && !mNewEventOccurred&& mObserverMap.contains(entry.getKey()))) {//下面这三句,和addObserve 中的操作一样 pushParentState(observer.mState);observer.dispatchEvent(lifecycleOwner, upEvent(observer.mState));popParentState();}}}
上面的observer其实是一个ObserverWithState对象,它是一个静态内部类
LifecycleRegister#ObserverWithState
static class ObserverWithState {State mState;LifecycleEventObserver mLifecycleObserver;ObserverWithState(LifecycleObserver observer, State initialState) {//这里调用lifecycleEventObserver,生成一个事件观察者mLifecycleObserver,//每个生命周期,要发送给谁,都是通过这个变量来实现的(它是一个接口,有不同的实现)mLifecycleObserver = Lifecycling.lifecycleEventObserver(observer);mState = initialState;}void dispatchEvent(LifecycleOwner owner, Event event) {//获取当前事件的下一个状态State newState = getStateAfter(event);mState = min(mState, newState);//生命周期的分发,最终在这里调用到 自己实现的mLifecycleObserver.onStateChanged(owner, event);//这里会在回调完成后,才更新状态mState = newState;}}
调用了Lifecycling.getCallback方法来获得GenericLifecycleObserver 的实例,通过这个实例调用onStateChanged
static LifecycleEventObserver lifecycleEventObserver(Object object) {boolean isLifecycleEventObserver = object instanceof LifecycleEventObserver;boolean isFullLifecycleObserver = object instanceof FullLifecycleObserver;if (isLifecycleEventObserver && isFullLifecycleObserver) {return new FullLifecycleObserverAdapter((FullLifecycleObserver) object,(LifecycleEventObserver) object);}if (isFullLifecycleObserver) {return new FullLifecycleObserverAdapter((FullLifecycleObserver) object, null);}if (isLifecycleEventObserver) {return (LifecycleEventObserver) object;}//通过反射,找到Lifecycle 自动生成的类 XXX_LifecycleAdapterfinal Class<?> klass = object.getClass();int type = getObserverConstructorType(klass);if (type == GENERATED_CALLBACK) {List<Constructor<? extends GeneratedAdapter>> constructors =sClassToAdapters.get(klass);if (constructors.size() == 1) {GeneratedAdapter generatedAdapter = createGeneratedAdapter(constructors.get(0), object);//最终使用XXX_LifecycleAdapter,创建SingleGeneratedAdapterObserverreturn new SingleGeneratedAdapterObserver(generatedAdapter);}GeneratedAdapter[] adapters = new GeneratedAdapter[constructors.size()];for (int i = 0; i < constructors.size(); i++) {adapters[i] = createGeneratedAdapter(constructors.get(i), object);}return new CompositeGeneratedAdaptersObserver(adapters);}return new ReflectiveGenericLifecycleObserver(object);}
这个方法大概意思就是,根据传进的LifecycleObserver进行判断,构造一个LifecycleEventObserver对象.
LifecycleEventObserver 是一个接口 有一个方法onStateChanged()
,有四种实现:
- FullLifecycleObserverAdapter
- SingleGeneratedAdapterObserver
- CompositeGeneratedAdaptersObserver
- ReflectiveGenericLifecycleObserver
本例中onStateChanged 函数会调用到下面这个类中
class SingleGeneratedAdapterObserver implements LifecycleEventObserver {private final GeneratedAdapter mGeneratedAdapter;SingleGeneratedAdapterObserver(GeneratedAdapter generatedAdapter) {mGeneratedAdapter = generatedAdapter;}@Overridepublic void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) {//mGeneratedAdapter 也就是Lifecycle 自动生成的类,这里特指P1_LifecycleAdaptermGeneratedAdapter.callMethods(source, event, false, null);mGeneratedAdapter.callMethods(source, event, true, null);}
}
下面来看下,自动生成的类P1_LifecycleAdapter,在不同的生命周期事件,调用不同的函数
使用注解,会自动生成。所以需要在依赖中添加kapt "androidx.lifecycle:lifecycle-compiler:2.2.0"
public class P1_LifecycleAdapter implements GeneratedAdapter {final P1 mReceiver;P1_LifecycleAdapter(P1 receiver) {this.mReceiver = receiver;}@Overridepublic void callMethods(LifecycleOwner owner, Lifecycle.Event event, boolean onAny,MethodCallsLogger logger) {boolean hasLogger = logger != null;if (onAny) {return;}if (event == Lifecycle.Event.ON_CREATE) {if (!hasLogger || logger.approveCall("p1Create", 1)) {mReceiver.p1Create();}return;}if (event == Lifecycle.Event.ON_START) {if (!hasLogger || logger.approveCall("p1Start", 1)) {mReceiver.p1Start();}return;}if (event == Lifecycle.Event.ON_RESUME) {if (!hasLogger || logger.approveCall("p1Resume", 1)) {mReceiver.p1Resume();}return;}if (event == Lifecycle.Event.ON_PAUSE) {if (!hasLogger || logger.approveCall("p1Pause", 1)) {mReceiver.p1Pause();}return;}}
}
四、Lifecycle为什么要使用Fragment
Lifecycle为什么要使用Fragment,为什么不直接把这些方法,在Activity中实现呢?
我个人认为有两个原因:
- 因为不是所有的页面都继承AppCompatActivity,为了兼容非AppCompatActivity
- Activity和Fragment都实现Lifecycle,避免代码重复
所以封装一个同样具有生命周期的Fragment来给Lifecycle分发生命周期事件。
请点赞、收藏,感谢大家的支持
参考:
https://blog.csdn.net/xfhy_/article/details/88543884
https://juejin.im/post/5bf3cb46f265da612239f612
https://www.jianshu.com/p/2c9bcbf092bc
https://blog.csdn.net/quiet_olivier/article/details/103384146
Lifecycle 使用与源码分析——彻底搞懂Lifecycle原理相关推荐
- Android源码分析—属性动画的工作原理
转载请注明出处: http://blog.csdn.net/singwhatiwanna/article/details/17853275 前言 本文为Android动画系列的最后一篇文章,通过对源码 ...
- Lifecycle 使用与源码分析
一.Lifecycle 介绍 Lifecycle是一个生命周期感知组件,一般用来响应Activity.Fragment等组件的生命周期变化,并将变化通知到已注册的观察者.有助于更好地组织代码,让代码逻 ...
- Java 源码出发彻底搞懂String与StringBuffer和StringBuilder的区别
导读 在Java中数据类型分为基本数据类型与引用数据类型.其中String属于引用类型,也是最常见的一种类型.但是我们对于String了解多少呢?String对象的内存地址?如何创建String对象? ...
- 开启mybatis日志_Mybatis源码分析之Cache二级缓存原理 (五)
一:Cache类的介绍 讲解缓存之前我们需要先了解一下Cache接口以及实现MyBatis定义了一个org.apache.ibatis.cache.Cache接口作为其Cache提供者的SPI(Ser ...
- 极光实时监听怎么调用_源码分析 Sentinel 实时数据采集实现原理(图文并茂)
本篇将重点关注 Sentienl 实时数据收集,即 Sentienl 具体是如何收集调用信息,以此来判断是否需要触发限流或熔断. Sentienl 实时数据收集的入口类为 StatisticSlot. ...
- Android属性动画赏析,Android源码分析—属性动画的工作原理
前言 本文为Android动画系列的最后一篇文章,通过对源码的分析,能够让大家更深刻地理解属性动画的工作原理,这有助于我们更好地使用属性动画.但是,由于动画的底层实现已经深入到jni层,并且涉及到显示 ...
- 鸿蒙内核源码分析系列 | 读懂HarmonyOS内核源代码!
本系列从HarmonyOS架构层视角整理成文, 并用生活场景及讲故事的方式试图去解构内核,一窥究竟.帮助你读懂并快速理解鸿蒙操作系统源码. 1.鸿蒙内核源码分析(调度机制篇) 2.鸿蒙内核源码分析(进 ...
- 源码分析 Sentinel 实时数据采集实现原理
本篇将重点关注 Sentienl 实时数据收集,即 Sentienl 具体是如何收集调用信息,以此来判断是否需要触发限流或熔断. 本节目录 1.源码分析 StatisticSlot 1.1 Stati ...
- nginx源码分析之内存池实现原理
建议看本文档时结合nginx源码: 1.1 什么是内存池?为什么要引入内存池? 内存池实质上是接替OS进行内存管理,应用程序申请内存时不再与OS打交道,而是从内存池中申请内存或者释放内存到内存池, ...
最新文章
- Go 语言实现字符串匹配算法 -- BF(Brute Force) 和 RK(Rabin Karp)
- Element 2.6.0 发布,基于 Vue 2.0 的桌面端组件库
- ubuntu16.04开机卡死解决方案
- python如何计算整数和_Python中整数和浮点数
- 空间句法软件_【特训营2:空间句法高阶班】GIS中的空间句法运用 丨城市数据派...
- 如何发布你的Android应用程序
- WSUS客户端无法发现
- 【数据结构笔记33】C实现:希尔排序、增量序列
- Quartz 触发器、过期触发策略 、排它日历、数据持久化
- Docker部署Ghost
- GBase8a数据库中表的comment信息
- 做竞品分析常常借用的信息分析工具和网站
- 百度、谷歌搜索引擎接口
- 判断计算机电脑是否通电,电脑日常维护:查看硬盘通电时间,判断性能
- 【数据集划分】误用shuffle,导致训练集和测试集掺混
- 张国荣5周年祭辰 张学友梁朝伟等红馆唱悼哥哥
- 获取二维数组的长度和宽度
- http://www.vgm8.com/Search.asp?key=%B6%F1%C4%A7%B3%C7
- 神武手游宠物加点方法及属性参考
- 秦皇岛达内传授零基础怎样学平面设计
热门文章
- 一颗 “不安分” 的螺丝钉
- 2、TWS API接口的使用说明
- 经济基础知识(初级)【15】
- CAS-认证流程详解
- Forecasting: Principles and Practice读书笔记Chapter 3
- 深圳国际智能家居展览会
- 机器学习案例——客户流失预测
- 石油管道巡线案例:SABER无人机高原2500米轻松作业
- 云卷云舒:2022 数据库总结从Gartner到IDC
- A 0.18um CMOS SOC for a 100-m-Range 10-Frame/s 200x96 pixel time-of-flight Depth Sensor翻译