本文主要介绍在应用发起内存申请,到操作系统最终分配内存,采用了那些途径和方法,并比较各种方法的优劣以及使用过程中应该注意那些点。
注意本文都是概述,如想详细了解,需单独详细了解每一部分内容
1、应用在那些情况下发起内存申请
2、内存发起申请的步骤(3)
3、内存申请过程中对jvm内存模型的使用
4、申请内存用到哪些算法
5、堆和堆内存分配
1、应用发起请求,要求系统分配内存
(这里不考虑堆外内存,后续单独解释堆外内存)
1)、init阶段,final和static修饰的类和方法
2)、应用中new()方法
3)、创建类时创建父类的对象申请内存
4)、java动态创建对象时反射技术(javaassist、asm等)
2、应用发起申请一般分为3部:
1)、创建对象实例
2)、为此对象分配内存
3)、指针指向内存地址
一般我们在做单例模式或者防止出现假对象的时候,我们会用volatile来防止指令重排(关于volatile后续会专门介绍),其实表面上看就是三步变一步。
3、内存申请一定会涉及到对内存模型各部分的操作
不同的场景,对内存的分配一定是有所区别的。
1)、对象在创建阶段,在resolve阶段,会对静态化属性值进行内存分配,并初始化值=0(此时test=0),如果是有final static修饰的则将初始化值为定义值(此时test=10)
private final static int test = 10;
这样静态修饰的属性值分配在方法区。
2)、一个方法的开始,首先是方法的参数属性、返回值等入栈,在栈区分配空间,同时如果有对象的new则需要去堆中建立对象实例。
3)、在堆中创建对象实例时,一般是两种方式,列表和指针碰撞。在指向堆中的实例时候,一般也是两种方式,直接指向(如果方法变化会需要重新指定)和通过句柄池(会使用额外的空间存储句柄)
4)程序计数器 可以看做一个数据结构,在线程切换时候记录下当前的字节行数和状态,以便于切回后能快速定位执行
4、内存分配方法(也被称为快分配-tlab,慢分配-cas)
1)、TLAB(线程局部分配缓存技术))
thread local area buffer,在并发的时候为了提高内存分配的效率,在创建线程的时候为每个线程分配了一段内存,此时线程申请的时候在自己内部解决就好,这样就不用去考虑并发问题,同时分配内存的效率跟c语言差不多。当然如果对象过大,仍然有去堆里分配,所以并发问题都存在。这也是为什么eden generation的对象越小越好
2)、cas
cas进行内存分配时,分配内存函数会返回top_add()返回 _top的eden区域的起始地址compare_to,当然也返回end_add()返回eden区域的结束值。在进行cas比较适合,compare_to与预期值进行比较,如果相同,则其他线程没有操作该比变量。将_newtop赋值给_top,将其变成真正的eden的启示值。这种方式也就叫指针碰撞
在进行内存分配的过程中,堆是最大的,也是java开发中用的最多的,所以着重分析一下堆。
5、堆和堆内存分配
此处分三部分解释:堆的创建 、堆内存的分配 和 垃圾回收
堆 是jvm虚拟机单独开辟出来的一块空间,由虚拟机自己管理,用来满足对象实例的分配的空间需求。
堆为什么分代? 在创建的对象中,由的对象很大,由的对象生命周期很长,而大多数对象的都会很快被回收。如果都在eden区域,eden区域采用的复制算法,对大和生命周期长的对象,是十分浪费cpu等资源的。因此将对象分代,不同代采用不同的算法回收。
1)、堆的初始化
堆是universe根据initial_heap来完成java堆初始化,具体要根据虚拟机配置。当然会根据回收算法,配置回收策略。
eg:若虚拟机配置UseParallelGC,则Java堆的堆类型为ParallelScavengeHeap(并行收集堆)
默认虚拟机将使用GenCollectedHeap(分代收集堆)
其具体算法、堆类型和回收策略如下:
需要注意的一点就是,堆空间初始化完成以后,如果是64位环境会进行指针压缩和TLAB等相关内容。通常64位JVM消耗的内存会比32位的大1.5倍,这是因为在64位环境下,对象将使用64位指针,这就增加了一倍的指针占用内存开销。
2)、堆内存分配
堆在初始化完成以后,我们以GenCollectedHeap 分代堆为例来解释,一般GenCollectedHeap支持10个分代(一般只使用新生代和老年代)
那么GenCollectedHeap是如何向系统申请内存空间的呢?
答案就在allocate()函数中 ,在申请之前,当然要对内存空间的大小和分块数进行计算
默认的新生代和老年代的分块数为1,而永久代的分块数为2
后边涉及到的内容很多,需要篇幅较长,后续再解释。下面copy一张图过来,有兴趣的朋友可以看下
3)、堆回收有更多gc的内容,会单独介绍