JVM内存模型

1.程序计数器:是一个数据结构,用于保存当前正常执行的程序的内存地址。Java虚拟机的多线程就是通过线程轮流切换并分配处理器时间来实现的, 为了线程切换后能恢复到正确的位置,每条线程都需要一个独立的程序计数器,互不影响,该区域为“线程私有”。

2.Java虚拟机栈:线程私有的,与线程生命周期相同,用于存储局部变量表,操作栈,方法返回值。局部变量表放着基本数据类型,还有对象的引用。

3.本地方法栈:跟虚拟机栈很像,不过它是为虚拟机使用到的Native方法服务。

 hashcode方法是native的

wait(long times) notify  notifyAll也是native的

4.Java堆:所有线程共享的一块内存区域,对象实例几乎都在这分配内存。

5.方法区:方法区是被所有线程共享,所有字段和方法字节码,以及一些特殊方法如构造函数,接口代码也在此定义。简单说,所有定义的方法的信息都保存在该区域,此区属于共享区间

静态变量+常量+类信息(构造方法/接口定义)+运行时常量池存在方法区中

But 实例变量存在堆内存中,和方法区无关

堆和方法区

6.运行时常量池:代表运行时每个class文件中的常量表。包括几种常量:编译时的数字常量、方法或者域的引用。

堆、栈、方法区的联系

Student s = new Student("小明",18);

s 是指针,存放在栈中。

new Student("小明",18) 是对象 ,存放在堆中。

Student 类的信息存放在方法区。

 

在java中可以作为GC Roots的对象有以下几种:

1.虚拟机栈中引用的对象、

2.方法区类静态属性引用的对象、

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

4.本地方法栈JNI引用的对象

 Minor GC ,Full GC 触发条件

Minor GC触发条件:当Eden区满时,触发Minor GC。

Full GC触发条件:
(1)调用System.gc时,系统建议执行Full GC,但是不必然执行
(2)老年代空间不足
(3)方法去空间不足
(4)通过Minor GC后进入老年代的平均大小大于老年代的可用内存

(5)由Eden区、From Space区向To Space区复制时,对象大小大于To Space可用内存,则把该对象转存到老年代,且老年代的可用内存小于该对象大小。

原文地址

垃圾收集器

两个基本概念:

1)吞吐量=运行用户代码时间/(运行用户代码时间+垃圾收集时间)
2)停顿时间短则响应速度好提升用户体验;高吞吐量则CPU利用率高,适合后台运算

垃圾收集器 使用位置 使用算法 可配合收集器 描述 优点 缺点
Serial收集器 新生代 复制算法  

单线程

stop the world

JVM在Client模式下默认采用

简单

高效

单线程

stop the world

Serial Old 老年代 标记整理   Serial的老年代版本

简单

高效

单线程

stop the world

ParNew 新生代 复制算法  

Serial的多线程版本、

Server模式下默认收集器

默认线程数=CPU数量

多线程 stop the world
Parallel Scavenge 新生代 复制算法   多线程、目标关注吞吐量    
Parallel Old 老年代 标记整理  

Parallel Scavenge的老年代版本、

多线程、关注吞吐量

   
CMS收集器 老年代 标记-清除   总之, CMS垃圾收集器在减少停顿时间上做了很多给力的工作, 大量的并发线程执行的工作并不需要暂停应用线程。 当然, CMS也有一些缺点,其中最大的问题就是老年代内存碎片问题, 在某些情况下GC会造成不可预测的暂停时间, 特别是堆内存较大的情况下。

 

对CPU资源非常敏感

垃圾碎片

G1 新生代+老年代 复制+标记整理  

并行与并发

分代收集

空间整合

可预测的停顿

   

原文地址