JVM

内存模型

堆、栈、方法区、本地方法栈、程序计数器

栈:线程私有。局部变量表,操作栈,动态链接,方法出口,执行java方法

本地方法栈:线程私有。执行Native方法

程序计数器:线程私有。当前线程执行的字节码位置,为执行java方法服务

堆:内存中最大,线程共享。存放对象实例,分代管理。

方法区:线程共享。已被虚拟机加载的类信息,常量和静态变量。

类加载机制

类的加载:将编译好的class文件中的字节码读入到内存中,将其放在方法区并创建对应的class对象。

加载过程:加载(文件到内存)—链接(验证【文件内容验证:文件格式,元数据,字节码,符号引用验证,要符合规范】、准备【内存分配】、解析)—初始化(静态变量赋值)

类初始化的触发条件:

1.     创建类的实例

2.     访问类的静态方法或者静态变量

3.     Class.forname()反射类

4.     子类被初始化

双亲委派加载机制

常用类加载器

GC

为什么要回收?

回收垃圾,释放内存

什么时候回收?

新生代内存慢时,会出发minorGC

收回哪些对象?

1.     引用计数法

2.     引用可达法

 

GCRoots开始搜索—对象到GCRoots没有引用链相连,进行第一次标记—是否执行了finalize()

引用:无论通过哪种算法判断对象是否已死,判断都与引用有关。

1强引用:普遍存在的引用,只要引用存在,垃圾收集器就不会回收掉被引用的对象。

2.软引用:还有用但是非必须的对象。在系统将要发生内存溢出之前,会被列入回收范围。

场景:创建缓存的时候,创建的对象放在缓存中,当内存不足时,jvm就会回收早先创建好的对象,如图片,视频编辑器。

3.弱引用:生存到下一次垃圾回收之前。

 

4.虚引用:无法通过虚引用取得对象实例。

 

怎么回收?

分代垃圾回收机制。作用:优化GC性能。不同的对象处于不同的生命状态,及时对无用对象进行回收。

垃圾回收算法

1.标记清除算法

先标记需要回收的对象,完成后回收所有标记对象。

不足

1.效率问题。

2.空间问题。不连续内存碎片。

2.复制算法

相等的两块->每次使用一块->复制,清理

不足:内存缩小了一半。在对象存活率较高的时候进行较多的复制操作,效率变低。

3.标记-整理算法

在标记清除算法的基础上,让所有存活对象向一端移动,直接清楚掉端外之外的内存。

4.分代收集算法

新生代和老年代,根据各个年代的特点采用最合适的收集算法。新生代:大批对象死去,采用复制算法。

老年代中对象存活率较高,没有额外空间,使用标记-整理或标记清楚算法。

扩展:为什么需要两个survivor?

1.     如果没有两个,每一次GC,对象被送到老年代,老年代很快会被填满,会触发MajorGC,消耗时间

2.     S区保证经历16次minorGC,还在新生区存活的对象,才送到老年代。

3.     减少碎片化。保留一个不用,用于复制另一个和eden中存活的对象。

 内存分配策略

1.对象优先在eden分配。

2.大对象直接进入老年代。

3.长期存活的对象进入老年代。

4.空间分配担保。

 

 

posted @ 2019-06-30 10:34  hhhl  阅读(221)  评论(0)    收藏  举报