知识点总结

GC算法

标记-清除算法,标记-整理算法,复制算法,分代收集算法

垃圾收集器

(1)Serial收集器

只用一个线程回收,新生代和老年代串行,新生代复制算法,老年代标记-整理算法。需要“Stop The World”

(2)ParNew收集器

Serial收集器多线程版本,新生代并行,老年代串行,新生代复制算法,老年代标记-整理算法

(3)Parallel Scavenge收集器

新生代多线程收集器,复制算法

(4)Parallel Old收集器

Parallel收集器的老年代版本,老年代并行,老年代标记-整理算法

(5)CMS收集器

老年代收集器,标记-清除算法

分为四步:初始标记、并发标记、重新标记、并发清除

初始标记和重新标记仍需要“Stop The World”

(6)G1收集器

相比CMS具有两大优点:

空间整合:采用标记-整理算法

可预测停顿:降低停顿时间外,能让使用者在明确指定消耗在垃圾收集上的时间不得超过N毫秒。

取消了新生代和老年代的物理空间划分,将堆划分为若干个区域

什么时候触发Full GC

1、调用System.gc()

2、老年代空间不足

3、在堆中创建大对象

在堆中分配占用大量连续内存的大对象时,会直接进入老年代。此时,即使老年代有足够空间,但是没有足够大的连续空间,也会触发full gc

4、方法区空间不足

方法区中存放一些class的信息、常量、静态变量等数据,当系统中要载入的类,反射的类和调用的方法较多时,方法区可能会被占满。在未配置采用CMS GC时会触发full gc

5、CMS GC时出现promotion failed和concurrent mode failure

6、minor gc时统计到的晋升到老年代的平均大小大于老年代的剩余空间时

JVM内存组成

1、堆

2、方法区

堆空间分为新生代和老年代,新生代分为(Eden和Survivor),Survivor分为FromSpace和ToSpace

3、虚拟机栈

4、本地方法栈

5、程序计数器

GC如何判断一个对象为垃圾

1、引用计数法

对象拥有一个引用计数器,每当一个地方引用它时,计数值加一,引用失效时,计数减一。当计数值为0时,对象可以被回收。

目前主流的JVM不采用此种方法,因为无法解决循环引用的问题。

2、根搜索算法

以“GC Roots”为起点,向下搜索,走过的路径为引用链,当一个对象到GC Roots没有任何引用链相连时,此对象可被回收。

被GC判定为垃圾的对象一定会被回收吗?

不一定。宣告对象死亡要经过两次标记过程。

1、在对象与GC Roots间没有引用链时会被第一次标记并进行筛选。筛选条件为对象是否有必要进行finalize方法。若对象没有重写finalize方法或者finalize方法已经被调用过,则判定为没有必要执行finalize方法,直接回收。否则判定为有必要。

2、被判定为有必要执行finalize方法的对象会被放入一个F-Queue队列中,由一个虚拟机自动建立的低优先级的finalize线程去执行它,触发对象的finalize方法。GC会对F-Queue中的对象进行第二次小规模的标记,对象只要重新与引用链中的任意对象关联即可从F-Queue中移除,避免被回收。若第二次标记时还没有被引用,则会被回收。

finalize线程所谓的“执行”,表示虚拟机会触发对象的finalize方法,但不确保会等待它运行结束。因为如果一个对象的finalize方法执行缓慢或陷入死循环,将导致F-Queue队列中对象永远 陷入等待,甚至导致内存回收系统的崩溃。

新生代和老年代特点及区别

1、新生代:大部分情况java新建对象都从新生代分配内存,新生代分为Eden和Survivor(包括FromSpace和ToSpace)。大部分对象存活时间较短,会频繁触发minor gc。可以通过-Xmn设置新生代大小,-XX:SurvivorRation调整Eden和Survivor比例。

2、老年代:存放新生代中经过多次垃圾回收仍然存活的对象。major gc不会频繁执行。新建的对象也有可能直接在老年代上分配内存。

新生代老年代采用的收集器算法也不一样。

新生代转移到老年代的触发条件

1、长期存活的对象

2、大对象直接进入老年代

3、minor gc后survivor仍然放不下

4、动态年龄判断,大于等于某个年龄的对象超过survivor的一半,大于等于某个年龄的对象直接进入老年代

哪些对象可作为GC Roots
1、虚拟机栈中引用的对象

2、方法区中类静态属性引用的变量

3、方法区中常量引用的对象

4、本地方法栈中JNI(即一般说的Native方法)引用的对象

如何减少gc的开销

1、不要显式地调用System.gc()

2、尽量减少临时对象的使用

3、对象不用时最好显式置为null

4、尽量使用StringBuffer而不是String来累加字符串

5、能用基本类型int,long等就不用Integer,Long等包装类

6、尽量少使用静态对象变量

静态对象变量不会被gc,会一直占用内存

7、分散对象创建或删除的时间

集中创建大量对象,尤其是大对象,会突然要求大量内存,引发gc。集中删除大量对象,会产生大量垃圾对象。

引起内存溢出的原因

1、内存中加载的数据量过于庞大,如一次从数据库取出过多数据

2、集合类中有对对象的引用,使用完后未清空,使JVM无法回收

3、代码中存在死循环或循环产生过多重复的对象实体

4、使用的第三方软件中的BUG

5、启动参数内存值设置的过小

类加载机制

加载、验证、准备、解析、初始化、使用、卸载

加载:

1、根据类全名获得此类的二进制字节流

2、将二进制的静态存储结构转化为方法区的运行时数据结构

3、在堆中生成一个代表此类的java.lang.Class对象,作为方法区数据的访问入口

验证:

确保class文件中的字节流符合当前虚拟机的要求

准备:

为类变量分配内存并为类变量赋初值。只为类变量(static修饰)分配内存,初值指的是数据类型的零值。

解析:

将符号引用替换为直接饮用

初始化:

执行类构造器初始化类变量和其他资源

Http和Https

Http:超文本传输协议,明文传输

Https:安全套接字层超文本传输协议,Http+SSL协议,依靠证书来验证服务器身份,主要作用:加密传输、身份认证。(建立安全通道,保证数据传输的安全;确认网站的真实性)

主要区别:

1、https需要到ca申请证书,一般免费证书较少,需要一定费用

2、http是明文传输,https是具有安全性的SSL加密协议

3、http和https使用的完全不同的连接方式,用的端口也不一样,http是80端口,https是443端口

4、http的连接是无状态的;https协议是由HTTP+SSL协议构成的可进行加密传输,身份认证的网络协议比http协议安全。

通信步骤

1、客户端请求https连接

2、服务端将包含公钥的证书信息传给客户端

3、客户端与服务端协商SSL的安全等级,即信息加密等级

4、客户端根据加密等级建立密钥,根据公钥对密钥进行加密,传送给服务端

5、服务端利用私钥解密出密钥

6、服务端利用密钥加密与客户端的通信

单例模式

一个单一的类负责创建自己的对象,同时保证只有单个对象被创建。提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。

1、单例类只能有一个实例

2、单例类必须自己创建唯一的实例

3、单例类必须给其他所有对象提供这一实例

主要解决一个全局使用的类频繁创建与销毁

解决方案:判断是否存在该单例,若存在则返回,否则创建

关键代码:构造函数是私有的

class SingleObject {
    //创建一个SingleObject对象
    private static SingleObject instance;
    
    //构造函数为private,保证无法实例化
    private SingleObject() {}
    
    //获得唯一可用对象
    public static SingleObject getInstance() {
        return instance;
    }
    
    public static void doSomething() {
        System.out.println("Hello World!");
    }
}

几种实现方式:

1、懒汉式,线程不安全(没有加锁)

是否 Lazy 初始化:是

是否多线程安全:否

实现难度:易

描述:这种方式是最基本的实现方式,这种实现最大的问题就是不支持多线程。因为没有加锁 synchronized,所以严格意义上它并不算单例模式。
这种方式 lazy loading 很明显,不要求线程安全,在多线程不能正常工作。

class SingleObject {
    private static SingleObject instance;
    
    private SingleObject() {}
    
    public static SingleObject getInstance() {
        if(instance == null) {
            instance = new SingleObject();
        }
        return instance;
    }
}

2、懒汉式,线程安全

是否 Lazy 初始化:是

是否多线程安全:是

实现难度:易

描述:这种方式具备很好的 lazy loading,能够在多线程中很好的工作,但是,效率很低,99% 情况下不需要同步。
优点:第一次调用才初始化,避免内存浪费。
缺点:必须加锁 synchronized 才能保证单例,但加锁会影响效率。
getInstance() 的性能对应用程序不是很关键(该方法使用不太频繁)。

class SingleObject {
    private static SingleObject instance;
    
    private SingleObject() {}
    
    public static synchronized SingleObject getInstance() {
        if(instance == null) {
            instance = new SingleObject();
        }
        return instance;
    }
}

3、饿汉式

是否 Lazy 初始化:否

是否多线程安全:是

实现难度:易

描述:这种方式比较常用,但容易产生垃圾对象。
优点:没有加锁,执行效率会提高。
缺点:类加载时就初始化,浪费内存。
它基于 classloder 机制避免了多线程的同步问题,不过,instance 在类装载时就实例化,虽然导致类装载的原因有很多种,在单例模式中大多数都是调用 getInstance 方法, 但是也不能确定有其他的方式(或者其他的静态方法)导致类装载,这时候初始化 instance 显然没有达到 lazy loading 的效果。

class SingleObject {
    private static SingleObject instance = new SingleObject();
    
    private SingleObject() {}
    
    public static SingleObject getInstance() {
        return instance;
    }
}

4、双检锁/双重校验锁(DCL)

JDK 版本:JDK1.5 起

是否 Lazy 初始化:是

是否多线程安全:是

实现难度:较复杂

描述:这种方式采用双锁机制,安全且在多线程情况下能保持高性能。
getInstance() 的性能对应用程序很关键。

class SingleObject {
    private static SingleObject instance;
    
    private SingleObject() {}
    
    public static SingleObject getInatance() {
        if(instance == null) {
            synchronized(SingleObject.class) {
                if(instance == null) {
                    instance = new SingleObject();
                }
            }
        }
        return instance;
    }
}

5、登记式/静态内部类

是否 Lazy 初始化:是

是否多线程安全:是

实现难度:一般

描述:只有当调用getInstance时才会显式装载SingletonHolder类

public class Singleton {  
    private static class SingletonHolder {
        private static final Singleton INSTANCE = new Singleton();
    }
    private Singleton(){}
    public static final Singleton getInstance() {
        return SingletonHolder.INSTANCE;
    }
} 

6、枚举

JDK 版本:JDK1.5 起

是否 Lazy 初始化:否

是否多线程安全:是

实现难度:易

描述:实现单例模式的最佳方法,更简洁,它不仅能避免多线程同步问题,而且还自动支持序列化机制,防止反序列化重新创建新的对象,绝对防止多次实例化。

public enum Singleton {  
    INSTANCE;
    public void whateverMethod() {
        
    }
} 

B树和B+树区别

1、B+树内部节点中,关键字的个数与子树的个数相同,B树中关键字的个数总比子树个数少1

2、B+树中所有指向文件的关键字及其指针都在叶子节点中,B树中有的指向文件的关键字在内部节点中。

3、B+树中内部节点仅仅起索引作用。

4、B+树中在搜索时如果查询和内部节点的关键字一致,搜索过程不停止,而是继续向下搜索这个分支,而B树会停止。

5、B+树的叶子节点都是相连的,便于区间查找和遍历

B+树的优势

1、磁盘读写代价更低

内部节点没有指向关键字具体信息的指针,一次性读入内存中需要查找的关键字也就越多。

2、查询效率更加稳定

任何关键字的查找都必须偶从根节点到叶子节点,查询路径长度相同,导致每一次查询效率相当。

3、更有利于对数据库的扫描

由于叶子结点相连且存储全部数据,只要扫描叶子节点就可以完成遍历。

Collection和Collections区别

1、Collection是集合类的上层接口,是一个接口,包含集合类的基本操作

2、Collections是集合类的工具类,是一个类,用于对集合进行排序,搜索和线程安全等操作。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,776评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,527评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,361评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,430评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,511评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,544评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,561评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,315评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,763评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,070评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,235评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,911评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,554评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,173评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,424评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,106评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,103评论 2 352

推荐阅读更多精彩内容