一、栈、堆、方法区
java虚拟机的内存分为三个区域:栈stack、堆heap、方法区method area(方法区其实也在堆里,因为作用特殊,所以单独列出)
栈的特点:
1、栈描述的是方法执行的内存模型。每个方法被调用都会创建一个栈帧(存储局部变量、操作数、方法出口等)
2、JVM为每个线程创建一个栈,用于存放该线程执行方法的信息(实际参数、局部变量等)
3、栈属于单个线程私有,不能线程间共享!
4、栈的存储特性是“先进后出,后进先出”
5、栈是由系统自动分配,速度快!展示一个连续的内存空间。
堆的特点:
1、堆用于存储创建好的对象和数组(数组也是对象,见到new时,便在堆中开辟的一个空间存放对象了)
2、JVM只有一个堆,被所有线程共享
3、堆是一个不连续的内存空间,分配灵活,速度慢!
方法区(静态区)的特点:
1、JVM只有一个方法区,被所有线程共享!
2、方法区实际也是堆,只用于存储类、常量相关的信息!
3、用于存放程序中永远不变或唯一的内容(类信息【class对象】、静态变量、字符串常量等)
二、Garbage Collection
回收的核心是:
1、发现无用的对象
2、回收无用对象占据的空间
垃圾回收算法:
1、引用计数法:当前被使用的数为0,即为无用节点
堆中每个对象都有一个引用计数。被引用一次,计数加1,被引用变量值变为null,则计数减1,直到计数为0,则表示变成无用对象。优点是算法简单,缺点是无法识别“循环引用的无用对象”
2、引用可达法:在引用关系中,找到度为0的节点,即为无用节点
程序把所有的引用关系看做一张图,从一个节点GC ROOT开始,寻找对应的引用节点,找到这个节点以后,继续寻找这个节点的引用节点,当所有的引用节点寻找完毕之后,剩余的节点则被认为是没有被引用到的节点,即无用节点。
JVM将堆内存分为Eden、Survivor和Tenured/Old空间。
年轻代在Eden(伊甸园)、Survivor。年老代在Old。持久代在方法区内。
三、垃圾回收过程:
1、新创建的对象绝大多数会存储在Eden中。
2、当Eden满了(达到一定比例),不能再创建新对象,则触发垃圾回收(Minor GC),将无用的对象清理掉,然后将剩余对象复制到某个Survivor中,如S1,同时清空Eden。
3、当Eden再次满了,会将S1中的不能清空的对象存到另一个Survivor中,例S2。同时将Eden中不能被清除的对象复制到某Survivor中(如S1)。从而保证Eden和Survivor都被清理过。
4、重复多次(默认15次)Survivor中没有被清理的对象,则会被复制到老年代Old/Tenured区中。
5、当Old区满了,则会触发一次完整的垃圾回收(Full GC),
Minor(未成年) GC
用于清理年轻代区域,Eden区满了之后就会触发一次Minor GC,清理无用对象,将有用对象复制到“Survivor1”、“Survivor2”两个区,(这俩区大小空间相同,同一时刻只有一个在用,一个为空)
Major GC
达到年老代使用比例是,用于清理老年代区域
FUll GC
用于清理年轻代、年老代区域。成本较高,会对系统性能产生影响。所以JVM调优主要针对的一项内容就是Full GC