[LMKD] [Android] 进程OomAdj调整分析:OomAdj状态简要(1)

news2024/11/28 7:50:28

一. 什么是OomAdj

oomAdj是Android系统中的一个进程内存管理参数,它决定了系统在内存不足时回收进程的顺序。oomAdj的值越小,说明该进程越重要,越不容易被系统回收。Android系统会根据进程的oomAdj值来决定哪些进程应该被回收,以达到最大限度地提高系统的稳定性和性能。

二. OomAdj大概分析

可以通过ProcessList.java中的setOomAdj方法去调整进程的优先级, OOM_ADJ (Out-Of-Memory Adjustment),进程优先级影响系统对进程的内存回收策略。OOM_ADJ 值越低,表示该进程的优先级越高,系统回收内存时越不会杀死该进程。OOM_ADJ 值越高,则表示该进程的优先级越低,系统回收内存时越容易杀死该进程

在 Android 中,OOM_ADJ 值的范围为 -1000 到 1000,其中 -1000 表示最高优先级(最不容易被杀死),而 1000 表示最低优先级(最容易被杀死)。具体来说,-1000 到 -900 被认为是“native进程,系统进程”;-800 到 0 被认为是“系统常驻进程,前台进程,可见进程,可感知进程等”;而 1000 则被认为是“空进程”。

关于 -1000 和 1000 优先级的区别,主要体现在它们所代表的进程类型不同。具体来说:

  • -1000 优先级的进程是属于前台进程,这些进程通常是用户当前正在操作的应用程序。这些进程可以使用大量的系统资源,并且在系统内存不足时也不容易被杀死。因此,系统会尽量保留这些进程的内存,以保证用户体验的流畅性。
  • 1000 优先级的进程是属于空进程,即没有任何应用程序或服务的进程。这些进程不占用任何内存,因此在系统内存不足时,它们往往会被最先杀死。因此,这些进程通常只会被用来占位,或者用来作为一些系统服务的容器。
  • 可以在/proc/pid/oom_score_adj查看当前OomAdj值

在这里插入图片描述

三. 进程Adj值说明

  • static final int *INVALID_ADJ* = -**10000**:表示无效的adj值,也是个默认未初始化的值
  • static final int *UNKNOWN_ADJ* = **1001**:表示未知adj值,一般来说,这是要缓存的内容,但我们还不知道要分配的缓存范围中的确切值
  • static final int *CACHED_APP_MIN_ADJ* = **900**—>static final int *CACHED_APP_MAX_ADJ* = **999**:表示不可见,不活跃的进程,在任何情况下都可以杀死该进程,该类进程都是标记为cache进程,Empty进程,当Empty进程数量达到一定值,则会主动kill这些进程
  • static final int *CACHED_APP_LMK_FIRST_ADJ* = **950**:优先考虑杀死的进程对象,也是属于Empty进程
  • static final int *CACHED_APP_IMPORTANCE_LEVELS* = **5**:代表每个cache进程的OomAdj值的间隔,如果是同一个进程组内的间隔是紧挨着的,若不是则间隔5(cache进程都是在900~999以内)
  • static final int *SERVICE_B_ADJ* = **800**:服务分为A和B两大类,属于B类的服务没有那么活跃,比较”死寂”,容易被杀
  • static final int *PREVIOUS_APP_ADJ* = **700**:如果是上一个进程,而且拥有缓存的activity,adj类型是"previous”,例如在两个activity进行切换,那么上一个切换到后台的activity的优先级就是700
  • static final int *HOME_APP_ADJ* = **600**:这是一个只有home应用才有的adj值,通常是launcher应用的一个固定adj值,尽量避免杀死它,即使它通常在后台,因为用户与它的交互太多了,这里值的是不会高于600,如果回到launcher桌面,它的adj值仍然为0(应用所能达到的最低优先级)
  • static final int *SERVICE_ADJ* = **500**:一个进程持有一个服务,可能会是这个值,通常情况:Service的最近活跃时间在30分钟以内,会赋予Service所在进程adj值为SERVICE_ADJ(500),那Service30分钟内没有活跃,则不会是这个adj值。服务在没有任何客户端绑定或调用它的情况下可以保持运行的最长时间,超过这个时间(30分钟),系统将自动停止该服务以释放系统资源
  • static final int *HEAVY_WEIGHT_APP_ADJ* = **400**:一个进程如果任务很繁重,会赋予这个值,这个值在启动时在system/rootdir/init.rc中设置,尽量避免不被杀死,这是一个比较重要的进程,在AndroidManifest.xml设置了"android:cantSaveState=“true”“,同时系统配置了这个feature,那么其无法保存进程状态,由于无法保存状态,故尽量不要杀死, 一般只有一个,adj类型是"heavy”
  • static final int *BACKUP_APP_ADJ* = **300**:这是当前承载备份操作的进程,具体作用不明
  • static final int *PERCEPTIBLE_LOW_APP_ADJ* = **250**:用户可感知的最低级别,通常在客户端绑定服务端时设置了BIND_NOT_PERCEPTIBLE这个Context.flag,且客户端adj≤PERCEPTIBLE_APP_ADJ(可感知进程200,也就是客户端优先级低的情况,优先级越低,越容易保活)且当前进程的adj>250(该adj)的时候,会给该进程赋予PERCEPTIBLE_LOW_APP_ADJ。简单一点来说,就是客户端adj保活率很高,但是当前进程(服务端)保活率很低,则将当前进程设置一个合理的adj值:250,因为客户端在访问服务端时,不希望服务端被kill
  • static final int *PERCEPTIBLE_MEDIUM_APP_ADJ* = **225**:用户无法感知的进程,不过对于绑定到该服务端的客户端来说,它是可感知的,也就是对服务端对端的客户端来说,是可感知的
  • static final int *PERCEPTIBLE_APP_ADJ* = **200**:可感知进程的最低值,也就是可感知进程的最高保活率,比如当前进程正在后台播放音乐,后台正在打电话
  • public static final int *VISIBLE_APP_ADJ* = **100**:可见进程,经过调试home进程在后台时,就处于这个状态。如果处于远程动画播放状态,则会是这个状态。如果当前进程处于这个状态(自己是客户端),那么对端的服务端,则可能会被设置为该进程状态,是因为客户端对服务端的依赖,调整了服务端的adj
  • public static final int *PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ* = 50:拥有前台服务,而且最近在top顶端的时间在15s以内或者进程状态起码是PROCESS_STATE_TOP的优先级。
    也就是 :调整最近活跃的前台服务进程,在一段时间内(15s),继续像对待前台应用程序一样对待它。进程被移动到后台,不活跃时的状态,然后15s内在top级别(最前台),会被调整跟前台进程一样的待遇
  • public static final int *FOREGROUND_APP_ADJ* = **0** :当一个应用进程处于前台的时候,会是这个值
  • public static final int *PERSISTENT_SERVICE_ADJ* = **-700**:通常用于Service上,表示该服务是系统级别的常驻进程服务,此类服务被kill后会自启
  • public static final int *PERSISTENT_PROC_ADJ* = **-800**:表示这个是一个常驻进程,持久进程,被kill后会自启,通常是一个系统级别的进程,普通应用想要达到常驻进程状态,需要生命system.uid,代表这是一个系统进程,然后设置persistent标签即可
  • public static final int *SYSTEM_ADJ* = **-900**:代表这是一个系统进程,系统进程默认都是这个adj值,例如system_server是-900,并且不会改变。systemui即属于系统进程,又属于常驻进程,所以他会被分配到常驻进程里:-800
  • public static final int *NATIVE_ADJ* = **-1000**:代表属于一个native进程,非常重要的进程,不会被改变值,例如zygote进程pid是1,那么它属于一个native进程,adj值为-1000

四. 进程状态值说明

  • public static final int *PROCESS_STATE_UNKNOWN* = ProcessStateEnum.*UNKNOWN*;

    进程状态的初始值,进程的未知状态,无效状态,值为-1

  • public static final int *PROCESS_STATE_PERSISTENT* = ProcessStateEnum.*PERSISTENT*;

    最高优先级的进程状态,值为0,如果设置了该进程状态,代表这是一个系统进程,持久的系统进程。在oomAdjuster类中,如果客户端绑定服务端带有BIND_ABOVE_CLIENTBIND_IMPORTANT标记,且客户端adj ≤ -800(常驻进程adj),那么服务端会直接赋予最高优先级的进程状态(PROCESS_STATE_PERSISTENT

    再补充一点,在oomAdjuster调整中,会根据getMaxAdj是否≤前台应用adj(0),如果小于0的都是属于系统级别的进程,就会默认给到PROCESS_STATE_PERSISTENT进程状态

    if (state.getMaxAdj() <= ProcessList.FOREGROUND_APP_ADJ) {
                // The max adjustment doesn't allow this app to be anything
                // below foreground, so it is not worth doing work for it.
                if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
                    reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making fixed: " + app);
                }
                // 小于等于0的进程,都属于比较重要的进程
                // 所以type调整为fixed,为固定不可调整
                state.setAdjType("fixed");
                state.setAdjSeq(mAdjSeq);
                // 将进程之前设置最大adj(在processList#newProcessRecordLocked方法中
                // 会将系统进程设置setMaxAdj(ProcessList.PERSISTENT_PROC_ADJ))
                state.setCurRawAdj(state.getMaxAdj());
                // 默认是没有前景activity(默认值)
                state.setHasForegroundActivities(false);
                // 给的默认分组--分组分为SCHED_GROUP_BACKGROUND,SCHED_GROUP_TOP_APP,这两个比较常见
                state.setCurrentSchedulingGroup(ProcessList.SCHED_GROUP_DEFAULT);
                // 此类进程应用拥有最大的能力,CAMERA,MICROPHONE,NETWORK,LOCATION
                state.setCurCapability(PROCESS_CAPABILITY_ALL);
                // 设置进程状态,系统进程都设置为进程持久化状态
                **state.setCurProcState(ActivityManager.PROCESS_STATE_PERSISTENT);**
                // System processes can do UI, and when they do we want to have
                // them trim their memory after the user leaves the UI.  To
                // facilitate this, here we need to determine whether or not it
                // is currently showing UI.
                // 系统进程默认没有ui界面,也算个初始值
                state.setSystemNoUi(true);
                ...
    }
    

    客户端≤ -800,肯定是系统级别的进程了,系统级别的进程去调用服务端,服务端的进程状态也被拉到最高

  • public static final int *PROCESS_STATE_PERSISTENT_UI* = ProcessStateEnum.*PERSISTENT_UI*;

    表示该进程属于常驻进程,持久进程,系统进程,不过该系统进程必须有UI界面,值为1,例如亮屏状态或者正在执行远程动画状态,那么该进程会被直接赋予PROCESS_STATE_PERSISTENT_UI,提升进程状态为 常驻进程UI级。例如systemui有机会赋予这个进程状态

  • public static final int *PROCESS_STATE_TOP* = ProcessStateEnum.*TOP*;

    该进程状态,值为2,表示进程作为当前的顶级activity,即它是当前用户正在与之交互的应用程序。当系统处于内存不足时,系统会尽量避免杀死处于 TOP 状态的应用程序。就算是灭屏,如果该activity仍然是顶级的,也是这个状态,在oomAdj调整策略中,不会给该进程调整到这个进程状态,而是在其他地方赋予的这个进程状态(看样子是在ATMS#updateSleepIfNeededLocked会赋予这个进程状态)

  • public static final int *PROCESS_STATE_BOUND_TOP* = ProcessStateEnum.*BOUND_TOP*;

    该进程状态,值为3,表示绑定到top应用的进程,在oomAdj调整策略中,当客户端的adj==PROCESS_STATE_TOP时,会将客户端的进程状态拉到PROCESS_STATE_BOUND_TOP

  • public static final int *PROCESS_STATE_FOREGROUND_SERVICE* = ProcessStateEnum.*FOREGROUND_SERVICE*;

    该进程状态,值为4,表示该进程是前台服务进程,运行在前台服务,如下代码,会将前台服务赋予该进程状态

    if (psr.hasForegroundServices()) {//是否属于前台服务
        // The user is aware of this app, so make it visible.
        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
        **procState = PROCESS_STATE_FOREGROUND_SERVICE;**
        state.bumpAllowStartFgsState(PROCESS_STATE_FOREGROUND_SERVICE);
        state.setAdjType("fg-service");
        state.setCached(false);
        // 默认分组
        schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
    }
    
  • public static final int *PROCESS_STATE_BOUND_FOREGROUND_SERVICE*=ProcessStateEnum.*BOUND_FOREGROUND_SERVICE*;

    该进程状态,值为5,表示绑定前台服务的进程,也就是该进程由于system的绑定(客户端绑定到服务端),会赋予该进程状态(绑定的前台服务状态)

  • public static final int *PROCESS_STATE_IMPORTANT_FOREGROUND* = ProcessStateEnum.*IMPORTANT_FOREGROUND*;

    该进程状态,值为6,表示这是一个重要的前台进程

    • 一般如果客户端进程状态 < PROCESS_STATE_TOP且客户端发起的绑定不属于前台服务(也没有像对待activity那样对待服务的flag),会在oom调整阶段赋予客户端这个进程状态
    • 如果hasExternalProcessHandles()为真,但服务端进程状态 > PROCESS_STATE_IMPORTANT_FOREGROUND ,会强制赋予这个进程状态
    • 如果进程的hasOverlayUi()返回真,例如下拉状态栏,锁屏界面,下拉通知栏等,也会赋予这个进程状态
  • public static final int *PROCESS_STATE_IMPORTANT_BACKGROUND* = ProcessStateEnum.*IMPORTANT_BACKGROUND*;

    该进程状态,值为7,表示这是一个重要的后台进程,对用户来说很重要,例如客户端绑定服务端(ConnectionRecord)带有Context.PROCESS_STATE_IMPORTANT_BACKGROUND 标识,则会赋予客户端这个进程状态

  • public static final [int](https://cs.android.com/android/platform/superproject/main/+/main:frameworks/base/core/java/android/app/ActivityManager.java;bpv=1;bpt=1;l=673?q=frameworks%2Fbase%2Fcore%2Fjava%2Fandroid%2Fapp%2FActivityManager.java&ss=android%2Fplatform%2Fsuperproject%2Fmain:frameworks%2F&gsn=int&gs=KYTHE%3A%2F%2Fkythe%3A%2F%2Fandroid.googlesource.com%2Fplatform%2Fsuperproject%2Fmain%2F%2Fmain%3Flang%3Djava%23int%2523builtin) [PROCESS_STATE_TRANSIENT_BACKGROUND](https://cs.android.com/android/platform/superproject/main/+/main:frameworks/base/core/java/android/app/ActivityManager.java;bpv=1;bpt=1;l=673?q=frameworks%2Fbase%2Fcore%2Fjava%2Fandroid%2Fapp%2FActivityManager.java&ss=android%2Fplatform%2Fsuperproject%2Fmain:frameworks%2F&gsn=PROCESS_STATE_TRANSIENT_BACKGROUND&gs=KYTHE%3A%2F%2Fkythe%3A%2F%2Fandroid.googlesource.com%2Fplatform%2Fsuperproject%2Fmain%2F%2Fmain%3Flang%3Djava%3Fpath%3Dandroid.app.ActivityManager%23828a91473ae3100fdbcfecedf45122b6da99fd42dd14513f60fd42de80186b33) = [ProcessStateEnum](https://cs.android.com/android/platform/superproject/main/+/main:frameworks/base/core/java/android/app/ActivityManager.java;bpv=1;bpt=1;l=674?q=frameworks%2Fbase%2Fcore%2Fjava%2Fandroid%2Fapp%2FActivityManager.java&ss=android%2Fplatform%2Fsuperproject%2Fmain:frameworks%2F&gsn=ProcessStateEnum&gs=KYTHE%3A%2F%2Fkythe%3A%2F%2Fandroid.googlesource.com%2Fplatform%2Fsuperproject%2Fmain%2F%2Fmain%3Flang%3Djava%3Fpath%3Dandroid.app.ProcessStateEnum%235c7affbcd4a8850d9a1fdc7af09e333d86189c9a15b21733f25432cb52c423ee).[TRANSIENT_BACKGROUND](https://cs.android.com/android/platform/superproject/main/+/main:frameworks/base/core/java/android/app/ActivityManager.java;bpv=1;bpt=1;l=674?q=frameworks%2Fbase%2Fcore%2Fjava%2Fandroid%2Fapp%2FActivityManager.java&ss=android%2Fplatform%2Fsuperproject%2Fmain:frameworks%2F&gsn=TRANSIENT_BACKGROUND&gs=KYTHE%3A%2F%2Fkythe%3A%2F%2Fandroid.googlesource.com%2Fplatform%2Fsuperproject%2Fmain%2F%2Fmain%3Flang%3Djava%3Fpath%3Dandroid.app.ProcessStateEnum%23676a1715b3502159ced8a831aa96b9273e3e118e21a2667e0e6aee3ef846e1e8);

    该进程状态,值为8,进程短暂的处于后台,因此我们将尝试继续运行,例如以下情况会在oom调整时赋予该进程状态

    • 例如adj > PERCEPTIBLE_APP_ADJ(可感知优先级) && 进程状态 > PROCESS_STATE_TRANSIENT_BACKGROUND,但是该进程状态的getForcingToImportant() ≠ null,代表强制给优先级不高的进程强制变更为正要的进程,会赋予这个进程状态,(调用AMS的setProcessImportant设置,强制提升优先级和进程状态)
    • 如果该进程属于BackupRecord(备份),则尽量避免被杀死,会将赋予这个进程状态值
    • 如果客户端绑定服务端(ConnectionRecord)不带有Context.PROCESS_STATE_IMPORTANT_BACKGROUND 标识,但是进程状态又有点高(值越低),例如clientProcState < PROCESS_STATE_TRANSIENT_BACKGROUND,则会赋予这个进程状态
  • public static final int *PROCESS_STATE_BACKUP* = ProcessStateEnum.*BACKUP*;

    该进程状态,值为9,该进程属于备份状态(具体作用不明),进程在后台运行备份/恢复操作会赋予这个进程状态,尽量不免被杀死
    例如能通过app.userId在AMS中获取到BackupRecord,则会赋予Backup_app_adj的adj值,进程状态高于这个值的时候,也会赋予这个进程状态,也就是进程优先级高了(优先级越高,值越低),我管不了高优先级的,但是优先级太低了,我就把你拉到这个进程状态

  • public static final int *PROCESS_STATE_SERVICE* = ProcessStateEnum.*SERVICE*;

    该进程状态,值为10,代表进程处于正在运行的前后台服务,也就是只要该进程存在服务,默认就是这个进程状态(后续可能会被调整)。
    oomAdjuster调整中,会根据top-activity,运行远程动画的activity,instrumentation,正在接收的广播,正在运行的服务,会赋予默认的进程状态

  • public static final int *PROCESS_STATE_RECEIVER* = ProcessStateEnum.*RECEIVER*;

    该进程状态,值为11,代表进程处于正在接收广播

  • public static final int *PROCESS_STATE_TOP_SLEEPING* = ProcessStateEnum.*TOP_SLEEPING*;

    该进程状态,值为12,当设备处于休眠状态,会赋予这个进程状态

  • public static final int *PROCESS_STATE_HEAVY_WEIGHT* = ProcessStateEnum.*HEAVY_WEIGHT*;

    该进程状态,值为13,代表进程处于后台,但是该进程无法保存和恢复状态,如AndroidManifest.xml设置了"android:cantSaveState=“true”“,同时系统配置了这个feature,由于其无法保存状态,故尽量不要杀死,adj类型是"heavy”

  • public static final int *PROCESS_STATE_HOME* = ProcessStateEnum.*HOME*;

    该进程状态,值为14,代表该进程状态属于home进程,也就是桌面的launcher,桌面应用的进程状态不能低于PROCESS_STATE_HOME(14),launcher需要一直运行,无论前后台,也是个持久进程,被kill后会自启。因为和launcher交互的会比较少, 故优先级设置较低

  • public static final int *PROCESS_STATE_LAST_ACTIVITY* = ProcessStateEnum.*LAST_ACTIVITY*;

    该进程状态,值为15,可以理解为该进程处于activity界面,但是按了home或者back回到了后台(activity发生stop时),会赋予这个进程状态。后台进程,在运行最后一次显示的activity,会赋予这个进程状态

  • public static final int *PROCESS_STATE_CACHED_ACTIVITY* = ProcessStateEnum.*CACHED_ACTIVITY*;

    该进程状态,值为16,进程正在缓存activity,代表缓存的activity,如果缓存数量达到cachedProcessLimit(受emptyProcessLimity影响,32-emptyProcessLimity = 16)上限,则会主动调用app.killLoced()杀死目前的进程,例如psr.isTreatedLikeActivity()为真且进程状态已经≥PROCESS_STATE_CACHED_EMPTY的情况,代表这个服务像对待activity那样对待它,故会赋予这个进程状态

  • public static final int *PROCESS_STATE_CACHED_ACTIVITY_CLIENT* = ****ProcessStateEnum.*CACHED_ACTIVITY_CLIENT*;

    该进程状态,值为17,所有内容同上,不同的是如果这个服务的客户端具有activity,即hasClientActivities()为真,才会赋予这个进程状态,也是超过16个这样的进程会被kill——>该进程是另一个包含activity进程的客户端,会是这个进程状态

  • public static final int *PROCESS_STATE_CACHED_RECENT* = ProcessStateEnum.*CACHED_RECENT*;

    该进程状态,值为18,缓存进程,且有一个activity是最近任务里的activity,具体被kill的逻辑也同上.
    有activity在最近任务mRecentTasks中,代表最近启动的activity,且当前进程状态>该进程状态,会设置为该进程状态

  • public static final int *PROCESS_STATE_CACHED_EMPTY* = ProcessStateEnum.*CACHED_EMPTY*;

    该进程状态,值为19,代表一个空进程,也是被缓存了的进程,当该状态的进程数量超越了ActivityManagerConstants#CUR_TRIM_EMPTY_PROCESSES—emptyProcessLimity上限(32/2=16个进程),且进程30分钟内没有活跃,则会主动调用app.killLoced()杀死目前的进程,原因就是存在空进程时间太长,被kil,实现就在OomAdjuster.java中——当然也可以不用等30分钟,也可以等待进程上限,也是16个(受ram不同,上限也不同,可客制化),原因:空进程存在的太多了,可以在这客制化上限数量

  • public static final int *PROCESS_STATE_NONEXISTENT* = ProcessStateEnum.*NONEXISTENT*;

    该进程状态,值为20,代表进程不存在,算个初始值,进程销毁期间也是这个值

五. 进程分组说明

  • static final int *SCHED_GROUP_BACKGROUND* = 0;
  • static final int *SCHED_GROUP_RESTRICTED* = 1;
  • static final int *SCHED_GROUP_DEFAULT* = 2;
  • public static final int *SCHED_GROUP_TOP_APP* = 3;
  • static final int *SCHED_GROUP_TOP_APP_BOUND* = 4;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1070019.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

arm-三盏灯流水

.text .global _start _start: 1.设置GPIOE寄存器的时钟使能 RCC_MP_AHB4ENSETR[4]->1 0x50000a28 LDR R0,0x50000A28 LDR R1,[R0] ORR R1,R1,#(0x3<<4) 第四位第五位都设置为1 STR R1,[R0] 写回2.设置PE10管脚为输出模式 GPIOE_MODER[21:20]->01 0x5000…

【数据结构】迷宫问题DFS非递归(c语言实现)

本来之前写过一个推箱子&#xff0c;就想着写个迷宫游戏&#xff0c;因为想着推箱子游戏里面也有墙&#xff0c;也有玩家的移动&#xff0c;比推箱子简单的是还不用判断前面是否有箱子的情况&#xff0c;但是自己写的迷宫游戏如果自己随机生成的迷宫地图的话&#xff0c;不一定…

Altium Designer培训 | 3 - PCB库创建篇

参考文章 http://t.csdnimg.cn/T6ykf PCB封装的元素 PCB焊盘&#xff0c;焊接器件用的。管脚序号&#xff0c;和原理图管脚一一对应。丝印&#xff0c;是实物本体的大小范围。1脚标识&#xff0c;定位器件的正反方向。阻焊&#xff0c;防绿油覆盖的&#xff0c;把铜露出来&…

使用Windows系统自带的安全加密解密文件操作步骤详解

原以为安全加密的方法是加密压缩包&#xff0c;有的需要用软件加密文件&#xff0c;可每次想往里面修改或存放文件都要先解密&#xff0c;不用时&#xff0c;还得去加密&#xff0c;操作步骤那么多&#xff0c;那多不方便呀&#xff0c;这里讲讲用系统自带的BitLocker加密工具怎…

基于SSM的固定资产管理系统的设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

Linux命令基本用法

1.用户相关命令 1.账号管理 命令作用useradd添加用户passwd设置密码usermod修改用户userdel删除用户su切换用户 例&#xff1a; [rootlocalhost ~]# useradd aaa [rootlocalhost ~]# su aaa [aaalocalhost root]$ su root 密码&#xff1a; [rootlocalhost ~]# passwd aaa …

DynamicIPAccess.java

package webspider_20230929_paypal;import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL;/*** 动态IP访问** author ZengWenFeng* date 2023.10.08* email 117791303qq.com* mobile 13805029595*/ pub…

CDN,DNS,ADN,SCDN,DCDN,ECDN,PCDN,融合CDN的介绍

一、CDN是什么&#xff1f; CDN的全称是Content Delivery Network&#xff0c;即内容分发网络。其基本思路是尽可能避开互联网上有可能影响数据传输速度和稳定性的瓶颈和环节&#xff0c;使内容传输得更快、更稳定。通过在网络各处放置节点服务器所构成的在现有的互联网基础之…

【List-Watch】

List-Watch 一、定义二、工作机制三、调度过程 一、定义 Kubernetes 是通过 List-Watch 的机制进行每个组件的协作&#xff0c;保持数据同步的&#xff0c;每个组件之间的设计实现了解耦。 用户是通过 kubectl 根据配置文件&#xff0c;向 APIServer 发送命令&#xff0c;在 …

Acwing.788 逆序对的数量

题目 给定一个长度为n的整数数列&#xff0c;请你计算数列中的逆序对的数量。 逆序对的定义如下:对于数列的第i个和第j个元素&#xff0c;如果满i<j且ali]>ali]&#xff0c;则其为一个逆序对;否则不是. 输入格式 第一行包含整数n&#xff0c;表示数列的长度。 第二行包…

Redis学习(九)SpringBoot实现(Pub/Sub)发布订阅

目录 一、背景二、Redis的发布订阅2.1 订阅单个频道常用命令 2.2 按规则&#xff08;Pattern&#xff09;订阅频道2.3 不推荐使用的原因 三、SpringBoot实现发布订阅3.1 RedisUtil.java 发布类1&#xff09;MessageDTO.java 实体类2&#xff09;发布测试 3.2 订阅实现方式一&am…

day10.8ubentu流水灯

流水灯 .text .global _start _start: 1.设置GPIOE寄存器的时钟使能 RCC_MP_AHB4ENSETR[4]->1 0x50000a28LDR R0,0X50000A28LDR R1,[R0] 从r0为起始地址的4字节数据取出放在R1ORR R1,R1,#(0x1<<4) 第4位设置为1STR R1,[R0] 写回2.设置PE10管脚为输出模式 G…

C#LINQ

LINQ&#xff08;Language Integrated Query )语言集成查询&#xff0c;是一组用于C#和VB语言的拓展&#xff0c;它允许VB或者C#代码以操作内存数据的方式&#xff0c;查询数据库。 LINQ使用的优点&#xff1a; 无需复杂学习过程即可上手。编写更少代码即可创建完整应用。更快…

okhttp4.11源码分析

目录 一&#xff0c;OKHTTP时序图 二&#xff0c;OKHTTP类图 三&#xff0c;OKHTTP流程图 一&#xff0c;OKHTTP时序图 上图是整个okhttp一次完整的请求过程&#xff0c;时序图里面有些部分为了方便采用了简单的描述&#xff0c;描述了主要的流程&#xff0c;细节的话&#…

数据结构之堆,栈的实现

首先我们分析由于只需要尾进尾出&#xff0c;用数组模拟更简单。 实现的功能如上图。 top可以表示栈中元素个数。 capacity表示栈的容量。 首先是堆的初始化 再就是栈的插入和删除 然后实现显示栈顶元素 大小和检测是否为空的实现 销毁栈的实现&#xff08;防止内存泄露&…

【无标题】Delayed延迟队列不工作

背景 项目中使用java 自带的延迟队列Delayed&#xff0c;只有添加进队列的消息&#xff0c;并没有被消费到 版本 jdk1.8 问题原因 上一个消费队列出现异常并且没有捕获&#xff0c;下一个队列就没有进行消费 复现代码 没有抛异常的情况下 package com.ccb.core.config.…

10.8c++作业

#include <iostream>using namespace std; class Rect {int width; //宽int height; //高 public://初始化函数void init(int w,int h){widthw;heighth;}//更改宽度void set_w(int w){widthw;}//更改高度void set_h(int h){heighth;}//输出矩形周长和面积void show(){co…

2023年铷铁硼行业分析:低端供应过剩,高性能材料供应不足[图]

铷铁硼材料是一种Fe基磁性材料&#xff0c;主要由钕铁硼按一定比例组成的四方晶体结构&#xff0c;其中Fe元素约占总质量的三分之二&#xff0c;Nd元素约占总量的三分之一&#xff0c;而B等含量最少&#xff0c;约占1%。铷铁硼是现今磁性最强的永久磁铁&#xff0c;也是最常使用…

波奇学C++:用红黑树模拟实现map和set

用同一个树的类模板封装map(key/value)和set(key) 红黑树的Node template<class T> struct RBTreeNode {RBTreeNode<T>* _left;RBTreeNode<T>* _right;RBTreeNode<T>* _parent;T _data;Colour _col;RBTreeNode(const T& data):_left(nullptr),_r…

python工具-内存采集展示

1. 查看某个进程的内存占用 1. 查看某个进程的内存占用 1.1. 采集1.2. 分析 1.1. 采集 下边内存保存为 cat-memory.sh 脚本文件&#xff0c;赋予可执行权限执行 ./cat-memory.sh pid 会生成 pid.txt #!/bin/bashprocess$1 out$1.txt pid$1echo 时间 内存(KB) >> $ou…