自动内存管理机制

1、内存区域与内存溢出

1.1、内存区域

程序计数器:当前线程所执行的字节码的行号指示器。当线程切换后,再次切换回来时,可以根据此计数器得知代码执行的位置,继续往下执行。

JAVA虚拟机栈:描述java方法执行的内存模型。存储(局部变量表--存储基本数据类型、操作栈、动态链接、方法出口等信息)。

本地方法栈:与虚拟机栈作用类似,不过他是用来服务与本地方法的(native方法)。

JAVA堆:对象实例以及数组都是在堆上分配空间。

方法区:存储被虚拟机加载的类的信息、常量、静态变量、编译后的代码数据等。也被叫做永久代。

运行时常量池:属于方法区的一部分。存放编译时生成的字面量和符号引用。

直接内存:使用native函数分配堆外内存。不受java堆大小限制。但是收到本机内存大小限制。

1.2、内存溢出

栈溢出:虚拟机栈、本地方法栈、

堆溢出:虚拟机栈、本地方法栈、运行时常量池、方法区、本机直接内存。

 

2、垃圾收集器与内存分配策略

1、判断对象是否存活?

引用计数法:有一个地方引用对象,就给对象的引用计数器+1。引用失效,则-1。  问题:无法解决两个对象之间互相引用的问题。

根搜索法:使用gcroot作为引用起点,看是否能达到对象的引用。

        gcroot可能包括:虚拟机栈(栈帧中的本地变量表)所引用的对象

                                     方法区中类静态属性引用的变量

                                     方法区中常量引用的对象

                                     本地方法栈中native方法引用的对象

 

2、JVM堆以及方法区(永久代)的内存回收

java堆主要回收死亡对象。根据以上两种方法,当一个对象被判定为已死亡,则需要进行回收。

永久代主要用来回收废弃常量(系统中无任何String对象引用常量池中的一个常量)以及无用的类(该类所有实例都被回收、加载该类的ClassLoader已被回收、该类的Class对象没有在任何地方被引用,也就是无法通过反射访问该类的方法)。

 

3、垃圾收集算法

标记清除法:首先标记需要回收的对象,最后统一回收。问题:效率低、产生大量不连续的内存碎片。

复制算法:将内存分为两块,将或者的对象复制到没使用的内存中,然后清理正在使用的那一块内存。 问题:内存缩小为原来的一半。目前是将内存分为8:1:1的三块,每次使用8+1,等到需要回收内存时,将存活的对象复制到最后那1中,然后回收最开始的8+1.

标记、整理算法:让活着的对象往一边移动,然后清理掉端边界以外的其他区域。

分代收集算法:根据对象存活周期不同将内存划分为几块。(新生代、老年代)根据不同的年代特点采用不同算法。

 

4、垃圾收集器

Serial 收集器:Client模式下默认的新生代收集器。单线程收集器(在此收集器工作时,必须停掉其他所有的工作线程!)

Serical Old 收集器:上述收集器的老年版本。使用标记--整理算法。

Parnew 收集器:Server模式下的新生代收集器。Serial收集器的多线程版本,还是会暂停掉工作线程,只是多个线程来处理垃圾回收。

Parallel Scavenge 收集器:与Par基本一致。不过关注点在于可以达到一个可控的吞吐量(运行代码的时间/运行用户代码的时间+垃圾回收的时间)。并且他有自适应调节策略,设置好虚拟机的内存参数,然后给收集器一个目标(更关注最大停顿时间、更关注吞吐量),收集器会根据目标自动调节相应参数,以达到目标。

Parallel 收集器:上述收集器的老年版本。使用标记-–整理算法。

CMS 收集器:以最短停顿时间为目标的收集器。使用标记–清除算法。问题:对cpu资源很敏感,当cpu资源较少时,用户线程会明显变慢。无法处理标记过后,用户线程产生的垃圾。因为他可以和用户线程同时进行。会产生大量不连续的碎片,没有足够大的连续内存来分配给大对象时,会导致FullGC。

它分为四个过程:

初始标记:标记gcroot可以直接关联到的对象

并发标记:根据以上的对象,进行搜索查询可以到达的对象

重新标记:修正并发标记期间因为用户程序导致以上搜索到的对象标记变化的标记记录

并发清除:gc线程与用户线程同时工作

由于并发清除阶段用户线程也在运行。所以jvm需要给用户线程留足够的内存空间。当其预留的内存空间不够程序运行时所需,则会引发Serical Old 收集器对老年代进行回收(详情请阅读深入理解Java虚拟机)

G1 收集器:使用标记–整理算法,精确的控制停顿时间(不牺牲吞吐量)。他将堆划分为多个大小固定的区域,然后在后台维护一个优先列表,根据允许收集的时间,优先回收垃圾最多的区域。

垃圾回收参数总结

 

5、内存分配策略(新生代:老年代=1:2,Eden:Survivor:Survivor=8:1:1)

对象优先分配到Eden区

大对象直接进入老年代(比如很长的字符串或者数组)

长期存活对象进入老年代

动态对象年龄判定(Survivor中相同年龄的对象大小总和大于此区域的一半,大于等于改年龄的对象直接进入老年代)

空间分配担保(gc后Survivor中仍然无法存放对象,这些对象进入老年代时,老年代需要根据以往进入老年代的对象的平均大小,判断此时空间是否够存储这些对象。否则,进行FullGC。)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值