详细的图又需要的,评论区留言,后面发给你

JVM事件大概回顾一下,主要就办了两件事呗:(当然细枝末节需要大家自己扣扣)

  • 小胡和敏小言去民政&局领证(类加载器和双亲委派机制,玩转~类加载器和双亲委派机制)
  • 一个打手和一堆打手地盘的故事(java内存区域或者运行时数据区域的故事,玩转~java内存区域或者运行时数据区域)

然后呢,最后剩下了几个主要点:

  • 打手们(线程们)私有的地盘他们自己可以打扫好,不用专人来帮忙
  • 打手们共享的区域中有俩地需要专人来帮们善后,打扫。
    • 打手们互相打斗完的舞台(,人称堆子哥),上面有很多脏牙套、xue渍、汗水…,需要专人来帮们善后,打扫。
    • 民政&局处理完给类似小胡和敏小言类似的办结婚证事件之后,会在方法区(人称区子哥)有废弃的纸张、图片等材料废材,所以也需要专人来帮们善后,打扫。

咱们上面所谓的来打扫的专人叫做GC垃圾回收器,是一个保洁集团。人家的公司标语倒也贴切“我们的服务宗旨是,就是让堆子哥和区子哥,永远~ 靓~白 ~白,无(垃)圾可施(工)”

好啦,开始施工呗,远方传来保洁施工队的阵阵施工声~
一个打手坐在拳台角上边擦汗边斜眼问道,你们这可别把我有用的东西给我错当垃圾给清了,到底有没有谱呀。(打手心里念叨,要不是我要陪我媳妇去叠烤肉,我早都自己来了)。
保洁队长说,大锅呀,nen(你)瞧瞧nen(你)说的这是啥话,我们是专业的哦。接着翘起指头说到,我们有一套专门的标准,里面有好几个方法来判断出您们客户哪些是垃圾(可回收)哪些不是垃圾(不能回收),有时候也说对象存活着就不是垃圾,没存活的对象就是垃圾

//被引用的对象就一定能存活吗?
//不一定,看 Reference 类型,弱引用在 GC 时会被回收,软引用在内存不足的时候,即 OOM 前会被回收,但如果没有在 Reference Chain 中的对象就一定会被回收。

打手:nen倒是说呀。
保洁队长:额(我)们有好多方法呢。bai急呀,先给你说 堆子哥 要得不呀?
打手:要得要得。

  • 引用计数法:(给每一个对象设置一个引用计数器,当有一个地方引用该对象的时候,引用计数器就+1,引用失效时,引用计数器就-1;当引用计数器为0的时候【任何时候计数器为 0 的对象就是不可能再被使用的】,就说明这个对象没有被引用,也就是垃圾对象,等待回收)

    • nen知道堆中的每个对象吧,额(我)们会 给每个对象的引用贴一张小纸条,就像这样,呸,再用口水贴上去,然后我们有专门的仪器来记录每个对象贴的纸条数。
    • 优缺点:
      • 优点:判定的效率也非常;这种算法是比较直接的找到垃圾,然后去回收,也被称为"直接垃圾收集"。
      • 缺点:如图中所示,无法解决循环引用的问题,当A引用B,B也引用A的时候,此时AB对象的引用都不为0,此时也就无法垃圾回收(a 对象引用了 b 对象,b 对象也引用了 a 对象,a、b 对象却没有再被其他对象所引用了,其实正常来说这两个对象已经是垃圾了,因为没有其他对象在使用了,但是计数器内的数值却不是 0,所以引用计数算法就无法回收它们),所以 一般主流虚拟机都不采用这个方法
      • 打手心里默念到,哇唔,口水…真…
  • 可达性分析算法:(从一个被称为GC Roots的对象为起始点向下搜索(搜索所走过的路径称为引用链(Reference Chain)),如果一个对象到GC Roots没有任何引用链相连接时或者说GC Roots到这个对象不可达时,说明此对象不可用)。请注意,可达~可到达 ~,我们公司有个很长的杆子,我们会找个起点,然后站在起点(起点就是一个被称为GC Roots的对象)上开戳,可达的(能戳到的)就是活着的(活着的就不是垃圾嘞,是不能回收的)

    • 根可达算法也是JVM 默认使用的寻找垃圾算法,它的原理就是定义了一系列的根,我们把它称为 “GC Roots” ,从 “GC Roots” 开始往下进行搜索,走过的路径我们把它称为 “引用链”当一个对象到 "GC Roots"之间没有任何引用链相连时,那么这个对象就可以被当做垃圾回收了

      • 根可达算法就可以避免计数器算法不好解决的循环引用问题,当多个对象彼此之前有引用关系,但是没有与"GC Roots"相连时,那么就会被当做垃圾所回收。
    • 在java中可以作为GC Roots的对象有以下几种:在java中有固定的GC Roots 对象和不固定的临时GC Roots对象
      • 固定的GC Roots:

        • 虚拟机栈(栈帧中的本地变量表)中引用的对象,譬如各个线程被调用的方法堆栈中使用到的参数、局部变量、临时变量等
        • 方法区中类静态属性引用的变量
          • 在方法区中类静态属性引用的对象,譬如 Java 类的引用静态变量
        • 方法区常量池中常量引用的对象,譬如字符串常量池中的引用
        • 本地方法栈JNI(譬如 Native 方法)引用的对象
        • Java 虚拟机内部的引用,如基本数据类型对应的 Class 对象,一些常驻的异常对象(空指针异常、OOM等),还有类加载器。
        • 所有被 Synchronized 同步锁持有的对象
        • 反应 Java 虚拟机内部情况的 JMXBean、JVMTI 中注册的回调本地代码缓存等。
      • 临时GC Roots:
        • 为什么会有临时的 GC Roots ?:目前的垃圾回收大部分都是分代收集和局部回收,如果只针对某一部分区域进行局部回收,那么就必须要考虑的当前区域的对象有可能正被其他区域的对象所引用,这时候就要将这部分关联的对象也添加到 GC Roots 中去来确保根可达算法的准确性。这种算法是利用了逆向思维,找到使用的对象,剩下的就是垃圾,也被称为"间接垃圾收集"。
    • 垃圾回收器是怎样寻找 GC Roots 的:根可达算法是通过 GC Roots 来找到存活的对象的,也定义了 GC Roots,那么垃圾回收器是怎样寻找GC Roots 的呢?
      • 首先,为了保证结果的准确性,GC Roots枚举时是要在STW的情况下进行的,但是由于 JAVA 应用越来越大,所以也不能逐个检查每个对象是否为 GC Root,那将消耗大量的时间。一个很自然的想法是,能不能用空间换时间在某个时候把栈上代表引用的位置全部记录下来,这样到真正 GC 的时候就可以直接读取,而不用再一点一点的扫描了。事实上,大部分主流的虚拟机也正是这么做的,比如 HotSpot ,它使用一种叫做 OopMap 的数据结构来记录这类信息。

        • OopMap 是做什么的?有什么好处?

          • 我们知道,一个线程意味着一个栈,一个栈由多个栈帧组成,一个栈帧对应着一个方法,一个方法里面可能有多个安全点。gc 发生时,程序首先运行到最近的一个安全点停下来,然后更新自己的 OopMap ,记下栈上哪些位置代表着引用枚举根节点时递归遍历每个栈帧的 OopMap ,通过栈中记录的被引用对象的内存地址,即可找到这些对象( GC Roots )。使用 OopMap 可以避免全栈扫描,加快枚举根节点的速度。但这并不是它的全部用意。

            • 安全点:从线程角度看,安全点可以理解成是在代码执行过程中的一些特殊位置,当线程执行到这些位置的时候,说明虚拟机当前的状态是安全的。比如:方法调用、循环跳转、异常跳转等这些地方才会产生安全点。如果有需要,可以在这个位置暂停,比如发生GC时,需要暂停所有活动线程,但是线程在这个时刻,还没有执行到一个安全点,所以该线程应该继续执行,到达下一个安全点的时候暂停,等待 GC 结束。

              • 有两种方式可以让线程在垃圾回收的时候都跑到最近的安全点呢?

                • 抢先式中断:就是在stw的时候,先让所有线程完全中断,如果中断的地方不在安全点上,然后再激活,直到运行到安全点的位置再中断。
                • 主动式中断:在安全点的位置打一个标志位,每个线程执行都去轮询这个标志位,如果为真,就在最近的安全点挂起。每个线程执行都去轮询时,有没有考虑如果有些线程处于sleep状态怎么办呢?为了解决有些线程处于sleep状态这种问题,又引入了安全区域的概念(安全区域是指在一段代码片中,引用关系不会发生改变,实际上就是一个安全点的拓展。当线程执行到安全区域时,首先标识自己已进入安全区域,那样,当在这段时间里 JVM 要发起 GC 时,就不用管标识自己为“安全区域”状态的线程了,该线程只能乖乖的等待根节点枚举完或者整个GC过程完成之后才能继续执行)。
          • OopMap的另外一个更根本的作用是,可以帮助 HotSpot 实现准确式 GC (即使用准确式内存管理,虚拟机可通过OopMap知道内存中某个位置的数据具体是什么类型)
      • 但是现在很多应用仅仅方法区都有好几百兆,如果逐个检查这里面的引用,那么会消耗很多时间:
  • 三色标记算法:就是垃圾回收器标记垃圾的时候使用的算法,
    • 将对象分为三种颜色

      • 白色:没被 GC 访问过的对象(被 GC 标记完后还是白色,就代表这个对象是垃圾)
      • 黑色:存活的对象
      • 灰色:被 GC 访问过的对象,但是对象引用链上至少还有一个引用没被扫描过
    • 在并发标记 的时候 可能会出现 误标的情况,
      • 这里举两个例子:

        • 1.刚开始标记为 垃圾 的对象,但是在并发标记过程中 变为了存活对象

          • 第一种情况影响还不算很大,只是相当于垃圾没有清理干净,待下一次清理的时候再清理一下就好了
        • 2.刚开始标记为 存活 的对象,但是在并发标记过程中 变为了垃圾对象
          • 第二种情况就危险了,正在使 用的对象的突然被清理掉 了,后果会很严重。那么 产生上述第二种情况的原因是什么呢?当下面这两种情况 都满足 的时候就会出现这种问题了

            • 1.新增一条或多条 黑色到白色对象的新引用
            • 2.删除 了灰色 对象到该白色对象 的直接引用或间接引用。
      • 所以为了解决这个问题,引入了 增量更新 (Incremental Update)和 原始快照 (SATB)的方案:
        • 增量更新破坏了第一个条件:增加新引用时记录 该引用信息,在后续 STW 扫描中重新扫描(CMS的使用方案)。
        • 原始快照破坏了第二个条件:删除引用时记录下来,在后续 STW 扫描时将这些记录过的灰色对象为根再扫描一次(G1的使用方案)。
  • 但一个对象满足上述条件的时候,不会马上被回收,也就是说 就算一个对象不可达也并非是非死不可的,暂时处于缓刑状态,要宣告这个对象死亡至少要经历两次标记过程
    • 第一次标记:如果对象在进行可达性分析后发现没有与GC Roots相连接的引用链,那么这个对象 将会被第一次标记并且进行一次筛选,筛选的条件是此对象是否有必要执行finalize()方法。-----书的作者有这么一句话“建议大家完全忘掉Java中的finalize()方法的存在”

      • 若对象没有覆盖finalize()方法或者finalize()方法已经被虚拟机调用过,此时虚拟机认为此对象没有必要执行finalize()方法(也就是判断当前对象是否有finalize()方法并且该方法没有被执行过)

        • 若这个对象被判定为有必要执行finalize()方法,那么会将当前对象放入F-Queue队列中,等待第二次小规模标记,并在稍后由一个虚拟机自动建立的、低优先级的finalize线程去执行(这个执行是指虚拟机会触发这个finalize()方法,虚拟机不保证该方法一定会被执行,原因是:)

          • 如果线程中的一个对象执行的很缓慢或进入了死锁,很有可能会导致F-Queue队列中其他对象永久处于等待,会导致回收系统的崩溃;

            • 另外就是任何一个对象的finalize()方法都只会被系统自动调用一次,当对象面临下一次回收时就不能再指望这执行finalize()进行自救了
    • 第二次标记:此时GC会对F-Queue中的对象进行 第二次小规模的标记,如果此时对象要在finalize()方法中拯救自己逃脱死亡命运,只要与引用链上的任何一个对象建立上关联即可(比如把自己(this关键字)赋值给某个类变量或者对象的成员变量,就可以在第二次标记时使自己被移出即将回收的范围之中),否则就会被真的回收。

哦对啦,还有我们公司有个新员工,叫小胡,有些对这个方法的补充,可以分享给你这个大老粗看看喽。乱用有风险哈,使用需谨慎…
好,说完了堆子哥到 区子哥,区子哥是用下面这个方法,不用上面俩方法。

  • 方法区(HotSpot虚拟机中的永久代),Java虚拟机规范中说的是方法区或者说永久代的垃圾收集效率很低

    • 永久代的垃圾收集主要回收两部分内容

      • 废弃常量:举个例子,比如说一个字符串(字面量)“hhb”已经进入了常量池中 但是没有任何一个String对象或者其他地方引用这个常量池中的"hhb"常量,如果此时发生内存回收必要时这个"hhb"就会被系统清理出常量池。常量池中的其他类、接口、方法、字段的符号引用等是类似的
      • 无用的类,
        • 类同时要满足下面三个条件这个类才能算是无用的类:【虚拟机可以对满足下述 3 个条件的无用类进行回收,这里说的仅仅是“可以”,而并不是和对象一样不使用了就会必然被回收

          • 该类所有的实例都已经被回收(Java堆中不存在该类的任何实例)
          • 加载该类的ClassLoader已经被回收
          • 该类对应的java.lang.Class对象没有在任何地方被引用,无法在任何地方通过反射访问到该类的方法们
        • 但是不是说满足了就被回收,是否对类进行回收,

老规矩,买一个图赠送一个图。
无论是引用计数还是根可达算法,判断一个对象是否为垃圾都要和引用挂钩,所以,咱们看看引用到底都有些啥:

  • java 四种引用类型:强引用、软引用、弱引用、虚引用是什么,有什么区别:【JDK1.2 之前,Java 中引用的定义很传统:如果 reference 类型的数据存储的数值代表的是另一块内存的起始地址,就称这块内存代表一个引用。】【在程序设计中一般很少使用弱引用与虚引用,使用软引用的情况较多,这是因为软引用可以加速 JVM 对垃圾内存的回收速度,可以维护系统的运行安全,防止内存溢出(OutOfMemory)等问题的产生

    • 强引用,就是在程序代码中普遍存在的普通的对象引用关系,我们使用的大部分引用实际上都是强引用,这是使用最普遍的引用,如 String s = new String("hhb")

      • 只要强引用还存在垃圾回收器就永远不会回收掉被引用的对象,当 内存空间不足,Java 虚拟机宁愿抛出 OutOfMemoryError 错误,使程序异常终止,也不会靠随意回收具有强引用的对象来解决内存不足问题
    • 软引用,用于维护一些可有可无(有用但是并非必须的对象)的对象(软引用用来描述那些有用但是没必要的对象。)。如果内存空间足够,垃圾回收器就不会回收它,只有在内存不足时或者说将要发生内存溢出异常时,系统则会回收软引用对象,如果回收了软引用对象之后仍然没有足够的内存,才会抛出内存溢出异常。JDK1.2后提供了SoftReference类来实现软引用
      // 软引用
      SoftReference<String> softRef = new SoftReference<String>(str);
      
      • 只要垃圾回收器没有回收它,该对象就可以被程序使用。软引用可用来实现内存敏感的高速缓存
      • 软引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用所引用的对象被垃圾回收,JAVA 虚拟机就会把这个软引用加入到与之关联的引用队列中
    • 弱引用,相比软引用来说,要更加无用一些,它拥有更短的生命周期(被弱引用关联的对象只能生存到下一次垃圾回收发生之前),当 JVM 进行垃圾回收时,无论内存是否充足,都会回收被弱引用关联的对象(垃圾回收器开始工作,会回收掉所有只被弱引用关联的对象)。JDK1.2后提供了WeakReference 实现类来实现弱引用。在 ThreadLocal中就使用了弱引用来防止内存泄漏
      WeakReference<String> weakRef = new WeakReference<String>(str);
      
      • 不过,由于垃圾回收器是一个优先级很低的线程, 因此不一定会很快发现那些只具有弱引用的对象。
      • 弱引用可以和一个引用队列(ReferenceQueue)联合使用,如果弱引用所引用的对象被垃圾回收,Java 虚拟机就会把这个弱引用加入到与之关联的引用队列中
    • 虚引用,也叫幽灵引用或者幻影引用。是一种形同虚设的引用,一个对象无法通过虚引用来取得一个对象实例,在现实场景中用的不是很多,它主要用来跟踪对象被垃圾回收的活动,也就是为一个对象设置虚引用关联的唯一目的就是能在这个对象被回收器回收时收到一个系统通知。在现实场景中用的不是很多,它主要用来跟踪对象被垃圾回收的活动。JDK1.2后提供了PhantomReference实现类来实现虚引用
      • 虚引用是最弱的一种引用关系,它的唯一作用是用来作为一种通知。如零拷贝(Zero Copy),开辟了堆外内存,虚引用在这里使用,会将这部分信息存储到一个队列中,以便于后续对堆外内存的回收管理。
      • 形同虚设,与其他几种引用都不同,虚引用并不会决定对象的生命周期。如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收。
      • 虚引用与软引用和弱引用的一个区别在于虚引用必须和引用队列(ReferenceQueue)联合使用。当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之关联的引用队列中。程序可以通过判断引用队列中是否已经加入了虚引用,来了解被引用的对象是否将要被垃圾回收。程序如果发现某个虚引用已经被加入到引用队列,那么就可以在所引用的对象的内存被回收之前采取必要的行动。

打手:知道啦知道啦,啥时候开扫呢,都快臭了。
保洁组长:要不是你我早开工了。兄得们,整起来…咱们分为五个小组哈…先上A组
A组:就叫做“标清”(标记清除法
打手心里默念:标清,我还高清呢,给谁一天天在那秀呢…
A组:不给您吹,我这标清,是先把垃圾们给"标记"出来,再把标记出来的垃圾给一个一个干掉。
不和你废话,直接上干货。

打手:不是听说有个啥买一赠一嘛,
保洁组长:肯定有呀,来呀,上货

  • 标记清除法(Mark-Sweep):

    • 算法分为标记和清除两个阶段

      • 第一步:利用 可达性 去遍历内存,把存活对象和垃圾对象分别进行标记
      • 第二步:在遍历一遍,将所有标记的对象回收掉
    • 优缺点:
      • 效率不行,标记和清除的效率都不高;(随着对象越来越多,那么所需要消耗的时间就会越来越多)
      • 标记和清除后会产生大量的不连续的空间分片,可能会导致之后程序运行的时候需分配大对象而找不到连续分片而不得不触发一次GC;(标记清除后会导致碎片化,如果有大对象分配很有可能分配不下而出发另一次的垃圾收集动作)

保洁组长:咳咳咳,咱们时间有限哈,上B组
B组:我们biao整~
打手:不要争,啥不要争。
B组:我们会再巡视一遍,会把不是垃圾的正派物件放在一块,no散放
打手:可以呀,还知道物以类聚,人以群分

别说话,买一赠一

  • 标记整理法: 这种算法可以说是结合了标记清除和复制两种算法,既有标记删除,又有整理功能

    • 第一步:利用 可达性 去遍历内存,把存活对象和垃圾对象进行标记;
    • 第二步:将所有的存活的对象向一段移动,将端边界以外的对象都回收掉
    • 特点:
      • 适用于存活对象多,垃圾少的情况;
      • 需要整理的过程,无空间碎片产生;这种算法就是通过标记清除算法找到存活的对象,然后将所有存活的对象,向空间的一端移动,然后回收掉其他的内存。

保洁队长:C组,赶紧上,快下班了都,抓点紧
C组,我们主要把我们所有的地盘平分为两块,一块用时另一块闲置,等把用的这一块用完了,就把这一块上的好东西放到闲置的那一块上,然后把之前用的这一块里面的脏垃圾处理一下。然后,换角色…
打手:啥
C组:算了,大老粗,直接给你上图吧

老规矩,不偏心,买一赠一

  • 复制算法(为了解决标记清除的效率问题): 将 内存按照容量大小分为大小相等的两块,每次只使用一块(对象只在其中一块区域内分配),当一块使用完了,就将还存活的对象移到另一块上,然后在把使用过的内存空间一次性清理掉;

    • 现在的商业虚拟机都采用 复制算法来回收新生代,但是新生代中的对象98%都是朝生夕死的所以 不用按照1:1来平分内存空间,而是将内存分为一块较大的Eden空间和两块较小的Survivor空间(HotSpot默认Eden和Survivor大小比例是8:1),每次使用Eden和其中一块Survivor

      • 回收时将Eden和Survivor中还存活的对象一次性都复制到另外一块Survivor空间上,最后清理掉Eden和刚才用过的Survivor空间

        • 当Survivor内存不够时需要依赖其他内存(老年代)进行分配担保,这些放不下的对象会直接通过分配担保机制进入老年代
    • 优缺点:
      • 优点:可以看到回收后的对象是排列有序的,这种操作只需要移动指针就可以完成,效率很高
      • 缺点:
        • 不会产生空间碎片;
        • 内存使用率极低,浪费过多的内存,使现有的可用空间变为原先的一半

保洁队长:D组上,上完吃饭
D组:我们是那啥,分代回收滴
打手:分代,爷爷、孙子…
保洁队长,nonono,大老粗,算了,给你上图吧,一看便知

  • 分代收集算法: 根据内存对象的存活周期不同,将内存划分成几块,java虚拟机一般将Java堆内存分成新生代和老生代

    • 在新生代中,有大量对象死去和少量对象存活,所以采用复制算法,只需要付出少量存活对象的复制成本就可以完成收集;
    • 老年代中因为对象的存活率极高,没有额外的空间对他进行分配担保,所以采用标记清理或者标记整理算法进行回收
  • 分代收集理论:大多数的垃圾回收器都遵循了分代收集的理论进行设计,它建立在两个分代假说之上:这两种假说的设计原则都是相同的:垃圾收集器应该将jvm划分出不同的区域,把那些较难回收的对象放在一起(一般指老年代),这个区域的垃圾回收频率就可以降低,减少垃圾回收的开销。剩下的区域(一般指新生代)可以用较高的频率去回收,并且只需要去关心那些存活的对象,也不用标记出需要回收的垃圾,这样就能够以较低的代价去完成垃圾回收
    • 两个分代假说:

      • 弱分代假说:绝大多数对象都是朝生夕灭的。
      • 强分代假说:熬过越多次数垃圾回收过程的对象就越难消亡。
    • 跨代引用假说:如果某个新生代的对象存在了跨代引用,但是老年代的对象是很难消亡的,那么随着时间的推移,这个新生代对象也会慢慢晋升为老年代对象,那么这种跨代引用也就被消除了。
      • 由于跨代引用是很少的,所以我们不应该为了少量的跨代引用去扫描整个老年代的数据,只需要在新生代对象建立一个记忆集来记录引用信息

        • 记忆集:将老年代分为若干个小块,每块区域中有 N 个对象,在对象引用信息发生变动的时候来维护记忆集数据的准确性,这样每次发生了 “Minor GC” 的时候只需要将记忆集中的对象添加到 "GC Roots"中就可以了。

嗖…嗖…嗖…
打手:哎呦,还来个这,我倒要看看你啥赠品,刚转过头
保洁员和四个组的组员已经撒腿像一楼大门跑去了
保洁组长边跑边说:我们饿了,明天再说
打手喊道,哎,你四四组就光说了个咋扫垃圾,还没说:

  • 你们四个组都用的啥工具呀,我咋给你们准备道具呢?
  • 或者,你也没说你们哪个组扫哪里呢?,

哎,你快回来,我已经忍受不住…
打手:算了,我也饿了,先吃饭再说吧,明在和他们细说。

巨人的肩膀:
深入理解Java虚拟机

java基础巩固-宇宙第一AiYWM:为了维持生计,JVM_Part4~(4种垃圾收集算法(标清、标整、复制、分代)、判断是否是垃圾(引用计数、根可达算法))、四种引用类型、整起相关推荐

  1. java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型五层模型TCP/IP四层模型、TCPUDPIP的故事【TCP三握四挥】)整起

    PART1:计算机网络体系可以大致分为一下三种, 每一层有自己对应的协议,每一层都是向上一层提供服务,每个分层中所有的协议都称为协议栈 协议:网络中传输信息时的规范和规则 各层一些重要的协议 网络:通 ...

  2. java基础巩固-宇宙第一AiYWM:为了维持生计,Redis基础Part2(Redis的数据结构)~整起

    PART1:Redis的数据结构:5+3数据类型<----------------->数据结构[未来随着 Redis 新版本的发布,可能会有新的数据结构出现,通过查阅 Redis 官网[[ ...

  3. java基础巩固-宇宙第一AiYWM:为了维持生计,Spring全家桶_Part1-1(Spring左膀右臂中的左膀IOC第一篇~全是概念,Spring为啥辣么6)~整起

    我Java学的好好的,为什么要学spring框架呀[一般说 Spring 框架指的都是 Spring Framework,它是很多模块的集合]?或者说,成天喊简化开发,spring是如何简化开发的?或 ...

  4. java基础巩固-宇宙第一AiYWM:为了维持生计,架构知识+分布式微服务+高并发高可用高性能知识序幕就此拉开(一:总览篇)~整起

    PART1:项目情景发展历程:很久很久以后,敏小言和老胡开的小超市,突然发生了一些变故: 超市中除了柜台格子业务之外,还有用户.视频.签到.评论.数据处理等业务[之前,咱们项目中的用户.视频.签到.评 ...

  5. java基础巩固-宇宙第一AiYWM:为了维持生计,手写RPC~Version07(RPC原理、序列化框架们、网络协议框架们 、RPC 能帮助我们做什么呢、RPC异常排查:ctrl+F搜超时)整起

    上次Version06说到了咱们手写迷你版RPC的大体流程, 对咱们的迷你版RPC的大体流程再做几点补充: 为什么要封装网络协议,别人说封装好咱们就要封装?Java有这个特性那咱就要用?好像是这样.看 ...

  6. java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之OS_Part_1整起(进程线程协程并发并行、进程线程切换进程间通信、死锁\进程调度策略、分段分页、交换空间、OS三大调度机制)

    PART0:OS,这货到底是个啥? OS,是个啥? OS的结构们: 存储器: 存储器的层次结构: 内存:我们的程序和数据都是存储在内存,我们的程序和数据都是存储在内存,每一个字节都对应一个内存地址.内 ...

  7. java基础巩固-宇宙第一AiYWM:为了维持生计,Redis基础Part6(Redis的应用场景、Redis是单线程的速度还快、Redis线程模型:Reactor模式、事件、发布订阅、管道)~整起

    PART1-1:为什么Redis是单线程的 Redis单线程是指: Redis的网络IO和键值对读写是由一个线程来完成的.这也是 Redis 对外提供键值存储服务的主要流程.Redis的其他功能,比如 ...

  8. java基础巩固-宇宙第一AiYWM:为了维持生计,大数据Hadoop之HDFS分布式文件系统(HDFS读写流程、主从集群两种问题“单点故障”及“压力过大内存受限”、HDFS的架构设计)~整起

    Hadoop之HDFS 目录 一.大数据 二.HADOOP 三.HDFS 1.HDFS基本概念 2.HDFS的架构设计 3.HDFS自己对于上面两种数据持久化技术的实现: 4.HDFS读写流程 5.H ...

  9. java基础巩固-宇宙第一AiYWM:为了维持生计,编程语言番外篇之机器学习(项目预测模块总结:线性回归算法、逻辑回归分类算法)~整起

    机器学习 一.机器学习常见算法(未完待续...) 1.算法一:线性回归算法:找一条完美的直线,完美拟合所有的点,使得直线与点的误差最小 2.算法二:逻辑回归分类算法 3.算法三:贝叶斯分类算法 4.算 ...

  10. java基础巩固-宇宙第一AiYWM:为了维持生计,Redis基础Part7(Redis常见使用(部署)方式:单机模式、主从模式、哨兵模式、集群模式)~整起

    Redis持久化:RDB.AOF是针对存储在一台服务器上的数据由于存储过程被打断而发生丢失的情况的.此时,咱们肯定要考虑到,所有鸡蛋都放在一个篮子里是会出问题的. 如果服务器发生了宕机,由于数据恢复是 ...

最新文章

  1. 单机PC手动更改windows update 地址
  2. 【转】gcc/g++ 链接库的编译与链接
  3. Linux下程序开机启动
  4. 小鹏NGP自动导航辅助驾驶Beta版体验:论软件,这台量产车可能是第一
  5. Rabbitmq学习笔记008---AmqpException: No method found for class java.lang.String
  6. Springboot之idea之pom文件图标不对
  7. web 开发安全性问题
  8. 关于CWMP基础(一)----(TR069)
  9. 手动实现一维离散数据小波分解与重构
  10. 今日睡眠质量记录74
  11. 基于docer 构建微服务基础设施
  12. 家用计算机做raid有用吗,磁盘阵列是什么?家用有必要磁盘阵列吗
  13. Python技能树的测评和CSDN Markdown编辑器的测评
  14. word-break:break-word、word-break:break-all和word-wrap:break-word 自动换行
  15. java 方法互斥_Java中的互斥方法执行
  16. 1数据类型、ER图、范式
  17. Java基础篇面试题49问与答 (2021最新版)
  18. 一步一步学区块链(1)概念了解
  19. 20句简短含蓄的爱情名言
  20. Python:Matplotlib库绘制散点图和折线图

热门文章

  1. 【一】ArcGIS API for JavaScript 4.x之地图显示
  2. 爱尔兰房产泡沫破灭带给我们…
  3. 全系列三极管应用参数和代换大全
  4. 大数据相关面试题整理-带答案-难一点
  5. Docker 学习新手笔记:从入门到放弃
  6. 2008年国际十大财经新闻
  7. 页面设计如何进行颜色搭配
  8. ssh 工具 socket 10106 连接不上
  9. 激光认证,激光安全等级认证,激光安全认证,激光等级认证,激光FDA认证。
  10. 多项式拟合缺点_常见算法优缺点