JVM总结---各处总结
堆与栈分开设计是为什么呢?
- 栈存储了处理逻辑、堆存储了具体的数据,这样隔离设计更为清晰
- 堆与栈分离,使得堆可以被多个栈共享。
- 栈保存了上下文的信息,因此只能向上增长;而堆是动态分配
线程栈
1、每当启动一个新线程的时候,java虚拟机都会为它分配一个java栈;
2、虚拟机只会对java栈执行两种操作:以栈帧为单位的压栈或者出栈;
3、它压入的每个栈帧(Stack Frame)是----程序指令 以及 局部变量表 ,每个方法调用对应一个栈帧。
局部变量表
包括==>:①各种基本数据类型;②对象的引用。
各种基本数据类型:
boolean、byte、char、short、int、float、long、double ;
4、我们需要注意到:每个 线程 都有 独立的栈 并且是互相隔离的。
栈的大小可以受到几个因素影响:
1️⃣一个是jvm参数 -XSS ;
2️⃣除了JVM设置,我们还可以在创建线程Thread的时候手工指定大小:
你在创建线程的时候参数传递进去,默认是1M
----------------------------------------------------------------------------------------
堆
1、Java 堆(Java Heap)是Java 虚拟机所管理的内存中最大的一块;
2、Java 堆是被所有线程共享的一块内存区域,在虚拟机启动时创建;
3、此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存;
①首先堆可以划分为新生代和老年代
新生代 ( Young ) 与老年代 ( Old ) 的比例的值为 1:2 ( 该值可以通过参数 –XX:NewRatio 来指定 )
②新生代又可以划分为一个Eden区和两个Survivor(幸存)区
1、按照规定,新对象会首先分配在Eden中(如果对象过大,比如大数组,将会直接放到老年代)。
2、在GC中,Eden中的对象会被移动到survivor中,直至对象满足一定的年纪(定义为熬过minor GC【当Eden区满时,触发Minor GC】的次数),会被移动到老年代。
它用于存储已被虚拟机加载的 类信息 ,常量, 静态变量, 即时编译后的代码 等数据
-----------------------------------------------------------------------------
①Minor GC 和 Full GC
Minor GC触发条件
:当Eden,Survivor区满时,触发Minor GC。
Minor GC ---采用的垃圾回收机制是 复制算法
因为:新生代每次垃圾回收倒要回收大部分的对象,也就说需要复制的操作次数较少,
但是在实际中并不是按照1:1比例来划分新生代空间的,一般来说,将新生代划分为一块较大的Eden代和两块较小的Survivor代,比例大概是
8:1:1;每次只是用Eden代,当进行回收时,将Eden代还存活的对象复制到一块Survor1对象中,然后清理掉
Eden代。第二次MinorGC会清理Eden代和Survor1,将对象存放到Survor2中,然后将Eden代和Survor1中的对象清理掉。当Survor2中的对象放不下的时候,会存放到 老年代;
Full GC触发条件:
(1)调用System.gc时,系统建议执行Full GC,但是不必然执行
(2)老年代空间不足
(3)方法区空间不足
(4)通过Minor GC后进入老年代的平均大小》大于老年代的可用内存
(5)由Eden区、From Space区向To Space区复制时,对象大小大于To Space可用内存,则把该对象转存到老年代,且老年代的可用内存小于该对象大小
使用到的垃圾回收算法:Mark-Compact算法
由于老年代的特点是每次回收的都是少量对象,一般使用的是 Mark-Compact 算法