Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

2019-10-27周会分享JVM(一)——分享人(袁乙文) #3

Open
Yueyuyu opened this issue Nov 6, 2019 · 0 comments
Open

2019-10-27周会分享JVM(一)——分享人(袁乙文) #3

Yueyuyu opened this issue Nov 6, 2019 · 0 comments
Labels
documentation Improvements or additions to documentation weekly meeting sharing Weekly meeting sharing

Comments

@Yueyuyu
Copy link

Yueyuyu commented Nov 6, 2019

1. Java内存区域

1.1.运行时数据区域

线程私有:
  1. 程序计数器
  2. 虚拟机栈
  3. 本地内存栈
共享:
  1. java堆
  2. 方法区
堆内存分配
  1. 对象优先在新生代区分配
  2. 新生代对象经过多次内存清理minorGC仍然存在就会成为老年代
  3. 大对象直接进入老年代
  4. 长期存活的对象进入老年代
  • 新生代 GC (Minor GC)

发生在新生代的垃圾回收动作,频繁,速度快。

  • 老年代 GC (Major GC / Full GC)

发生在老年代的垃圾回收动作,出现了 Major GC 经常会伴随至少一次 Minor GC(非绝对)。Major GC 的速度一般会比 Minor GC 慢十倍以上。

2.如何判断是否已死?

可达性分析法

通过一系列的 ‘GC Roots’ 的对象作为起始点,从这些节点出发所走过的路径称为引用链。当一个对象到 GC Roots 没有任何引用链相连的时候说明对象不可用。

可作为 GC Roots 的对象:

  • 虚拟机栈(栈帧中的本地变量表)中引用的对象
  • 方法区中类静态属性引用的对象
  • 方法区中常量引用的对象
  • 本地方法栈中 JNI(即一般说的 Native 方法) 引用的对象

如果对象在进行中可达性分析后发现没有与 GC Roots 相连接的引用链,那他将会被第一次标记并且进行一次筛选,筛选条件是此对象是否有必要执行 finalize() 方法。当对象没有覆盖 finalize() 方法,或者 finalize() 方法已经被虚拟机调用过,虚拟机将这两种情况都视为“没有必要执行”。

如果这个对象被判定为有必要执行 finalize() 方法,那么这个对象竟会放置在一个叫做 F-Queue 的队列中,并在稍后由一个由虚拟机自动建立的、低优先级的 Finalizer 线程去执行它。这里所谓的“执行”是指虚拟机会出发这个方法,并不承诺或等待他运行结束。finalize() 方法是对象逃脱死亡命运的最后一次机会,稍后 GC 将对 F-Queue 中的对象进行第二次小规模的标记,如果对象要在 finalize() 中成功拯救自己 —— 只要重新与引用链上的任何一个对象简历关联即可。

finalize() 方法只会被系统自动调用一次。

补充:四种引用

强引用

类似于 Object obj = new Object(); 创建的,只要强引用在就不回收。

软引用

SoftReference 类实现软引用。在系统要发生内存溢出异常之前,将会把这些对象列进回收范围之中进行二次回收。

弱引用

WeakReference 类实现弱引用。对象只能生存到下一次垃圾收集之前。在垃圾收集器工作时,无论内存是否足够都会回收掉只被弱引用关联的对象。

虚引用

PhantomReference 类实现虚引用。

3.垃圾回收算法

2.1 标记 — 清除算法

直接标记清除。

2.2 标记 — 整理算法

不同于针对新生代的复制算法,针对老年代的特点,创建该算法。主要是把存活对象移到内存的一端。

2.3 复制算法

把空间分成两块,每次只对其中一块进行 GC。当这块内存使用完时,就将还存活的对象复制到另一块上面。

大多数新生代对象不会熬过第一次 GC,所以不用 1 : 1 划分空间。分一块较大的 Eden 空间和两块较小的 Survivor 空间,每次使用 Eden 空间和其中一块 Survivor。当回收时,将 Eden 和 Survivor 中还存活的对象一次性复制到另一块 Survivor 上,最后清理 Eden 和 Survivor 空间。大小比例一般为 8 : 1 : 1,每次浪费 10% 的 Survivor。 如果存活的大于 10% ?采用分配担保策略:多出来的对象直接进入老年代。

@Yueyuyu Yueyuyu closed this as completed Nov 6, 2019
@Yueyuyu Yueyuyu reopened this Nov 6, 2019
@GeniusDSY GeniusDSY added documentation Improvements or additions to documentation weekly meeting sharing Weekly meeting sharing labels Nov 7, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation weekly meeting sharing Weekly meeting sharing
Projects
None yet
Development

No branches or pull requests

2 participants