java内存区域

对象的创建

虚拟机遇到new指令后,会先去检查在常量池中(运行时数据区-方法区)是否可以定位到一个类的符号引用,并检查这个符号引用代表的类是否已被加载、解析和初始化,如果没有,必须先执行相应的类的加载过程。

类加载检查通过后,虚拟机会为新生对象分配内存(堆上分配)

分配内存的方式:

1.指针碰撞:前提条件堆中内存是规整的,空闲的内存在一边,使用的内存在一边。中间放着一个指针作为分界点的指示器,需要多大内存,指针就滑向空闲等同的距离。

2.空闲列表:如果堆中内存不规则,使用的和空闲的交叉,那么虚拟机就需要维护一张表,记录那些内存是可用的,然后分配之后更新列表。

堆是否规整跟使用的垃圾回收器有关,如果垃圾回收器有标记整理的功能就会规整。

分配内存时如何解决并发问题:

1.使用同步功能(虚拟机采用CAS和失败重试保证原子性)

2.按照线程划分不同的空间进行分配(TLAB)

 对象的访问定位

对象的访问定位有两种方式:

1.使用句柄:如果对象移动,只需要改变句柄池中实例数据指针,而栈中的reference不需要修改

2.直接访问(Sun HotSpot采用该方式):速度更快,节省了一次指针对位的时间开销

 

内存分配和回收策略

对象主要分配在堆的新生代Eden区上,如果启动了本地线程分配缓冲,将按线程优先在TLAB上分配。

当Eden区没有足够空间进行分配时,虚拟机将进行一次Minor GC。

新生代分为Eden区、From Survivor、To Survivor,进行Minor GC。(新生代大小=Eden区+1个From Survivor区)

老年代是 Major GC/Full GC

大对象直接进入老年代(-XX:PretenureSizeThreshold,大于该值的直接进入老年代)

长期存活的对象进入老年代:虚拟机给每个对象分配了一个年龄计数器,如果对象在Eden区出生并经历过一次Minor GC后任然存活,并且被Survivor容纳,就会被移动到Survivor空间中,并且对象年龄设置为1,对象在Survivor区中每“熬过”一次Minor GC,年龄就加1,当达到设置的阈值(默认15,可以设置参数-XX:MaxTenuringThreshold)后,晋升到老年代中。

动态对象年龄判断:如果在Survivor空间中相同年龄所有对象大小的总和大于Survivor空间的一半,年龄大于或等于该年龄的对象就可以直接进入老年代

空间分配担保:在发生Minor GC之前,虚拟机先检查老年代最大可用的连续空间是否大于新生代所有对象总空间,如果成立,那么Minor GC可以确保是安全的。如果不成立,则虚拟机会查看HandlePromotionFailure设置值是否允许担保失败。如果允许,那么会继续检查老年代最大可用连续空间是否大于历次晋升到老年代对象的平均大小,如果大于进行一次Minor GC;如果小于或者HandlePromotionFailure设置不允许冒险,则进行Full GC。

 

转载于:https://www.cnblogs.com/share2perfect/p/10990132.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值