Java虚拟机的运行时区域:
Jvm内存分为线程共享区,线程独享区
1、共享区:
a.堆(主要存放实体):
1)·新生代(此算法主要是在回收这个区域)
·Eden 伊甸园(80%)
·Survior 存活区
·Tenured Gen
2) ·老年代(用标记整理算法)
b. 方法区(存放虚拟机加载的类信息,常量、静态变量、即时编译器编译后的代码等数据)
2、独享区:栈(存放java方法名、对象名)、本地方法栈(为jvm提供natvie服务)、程序计数器(记录程序执行的顺序)
内存分配策略
·1新创建对象优先分配到eden
·2大对象直接分配到老年代:因为大对象一般是用的比较久的,而新生区是经常垃圾回收,所以直接放老年代有助于提高效率
·3长期存活的对象分配到老年代
·4空间分配担保
·5动态对象年龄判断
垃圾回收
程序计数器、虚拟机栈、本地方法栈。这几个区域完全不用管回收问题,因为方法结束或者线程结束的时候他们所占用的内存就自然跟着一起释放了,3个区域随线程而生,随线程而灭。所以我们只需要管堆和方法区。尤其是堆,因为一个接口中的多个实现类需要的内存可能不一样,一个方法中的多个分支需要的内存也可能不一样,这部分内存的分配和垃圾回收都是动态的。
1、如何判定对象为垃圾对象
·引用计数法:在对象中添加一个引用计数器,当有地方引用这个对象的时候,引用计数器的值就+1,当引用失效的时候(设置对象=null),计数器的值就-1。当值为0时,被回收。缺点:当堆内存内部存在互相引用,而外部 没引用时,程序计数器值就不会为0,则不会被垃圾回收器回收,而我们看来这个对象应该被回收。
·可达性分析法:通过一系列的GC Roots的对象作为起始点,从这些根节点开始向下搜索,搜索所走过的路径称为引用链(Reference Chain),当一个对象到GC Roots没有任何引用链相连时,则证明此对象是不可用的。
说明:
(2.1)、红色代表不可达对象(可回收对象)
(2.2)、千万注意!!!!!上图并不是说方法区全可达,虚拟机栈部分可达,本地方法栈全部不可达,而只是为了说明这三个部分可以作为GC Roots!
可以作为GCRoots的对象:
·虚拟机栈
·方法区的类属性所引用的对象
·方法区中常量所引用的对象
·本地方法栈中引用的对象
2、如何回收
2.1回收策略
·标记-清除算法:就是当程序运行期间,若可以使用的内存被耗尽的时候,GC线程就会被触发并将程序暂停,随后将依旧存活的对象标记一遍,最终再将堆中所有没被标记的对象全部清除掉,接下来便让程序恢复运行。
存在两个问题:
效率问题:(递归与全堆对象遍历)
空间问题:这种方式清理出来的空闲内存是不连续的
·复制算法:此GC算法实际上解决了标记-清除算法带来的“内存碎片化”问题。首先还是先标记处待回收内存和不用回收的内存,下一步将不用回收的内存复制到新的内存区域,这样旧的内存区域就可以全部回收,而新的内存区域则是连续的。它的缺点就是会损失掉部分系统内存,因为你总要腾出一部分内存用于复制。
·标记-整理算法:首先还是“标记”,标记过后,将不用回收的内存对象压缩到内存一端,此时即可直接清除边界处的内存,这样就能避免复制算法带来的效率问题,同时也能避免内存碎片化的问题。老年代的垃圾回收称为“Major GC”。
·分代收集算法
·垃圾回收器
·Serial:(HotSport 的client端使用这个)单线程垃圾回收期,多个线程运行时,要全部停下,然后垃圾回收一下(单线程),然后再执行线程。因为是单线程,所以如果在垃圾回收量比较少时,效率是比较高的。
·Parnew:多线程。原理跟serial类似。使用复制算法回收(新生代)
·Parallel Scavenge:(HotSport 的Server端使用这个)主要是追求降低回收时间。
多线程,复制算法,达到可控制的吞吐量
(吞吐量:cpu用于运行用户代码的时间与cpu消耗的总时间的比值)
即吞吐量=运行用户代码时间/(运行用户代码时间+垃圾回收时间)
-XX:MaxGCPauseMillis垃圾收集器最大停顿时间
-XX:GCTimeRatio吞吐量大小(0,100)默认99
·Cms:Concurrent Mark sweep(使用标记清除算法)
工作过程:
·初始标记
·并发标记
·重新标记
·并发清理
优点:并发收集,低停顿
缺点:占用大量cpu资源,无法处理浮动垃圾,出现concurrent model failure,空间碎片。
·G1:最牛的垃圾收集器
优势
·并行与并发,与多核cpu相结合,缩短垃圾回收时间
·分代收集:(与新生代老年代有所区别的)
·空间整合,(类似标记整理算法)
·可预测的停顿
步骤:
1、初始标记
2、并发标记
3、最终标记
4、筛选回收
3、何时回收
添加虚拟机参数:可打印虚拟机的日志第一个是基本日志,加上第二个就是详细日志
-verbose:gc
-xx:+PrintGCDetail
虚拟机工具
jps查看当前的java进程,进程号、方法名
jstat 查看类装载,内存,垃圾收集器,jit编译的信息
jinfo:实时查看和调整虚拟机的各项参数
jmap:转换信息,转储堆块信息
jhat(jvm heap analysis tool),内存、cpu占用率很高
OQL object query language
SQL struct query language
jstack::查看虚拟机当前状况的线程快照(查看线程的信息)
JConsole 内存、线程监控,检测死锁。