这篇文章我们来讲一下jvm的内存分配方式
目录
1.概述
我们前面在GC那篇文章中写了JVM的内存分配策略,讲述了对象优先在Eden区进行分配等等几条策略,而这里又写JVM的内存分配方式,二者有什么区别吗?
区别就是:内存分配策略只是说我们应该怎么分配,相当于在分配应该遵循哪些准则;而本篇所写的内存分配方式则是讲对象在内存中具体怎么分配的,相当于是分配算法。相当于一个是战略一个是战术,一个是值方向,一个是教你怎么做。这就是二者的区别。
1.1jvm运行时数据区
jvm在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域。这些区域都有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启动而存在,有些区域则依赖用户线程的启动和结束而建立和销毁。Java虚拟机所管理的内存将会包括以下几个运行时数据区域:
其中方法区和堆是所有线程共享的数据区。程序计数器,虚拟机栈,本地方法栈是线程隔离的数据区
虚拟机栈和本地方法栈中的空间会随着方法的调用和完成而不断分配和释放。应用中创建的对象则会被分配到堆中,当对象不在使用的时候会被回收。
1.2堆空间的分代
下面看一下堆空间的分代:
1.3对象分配的整体流程
2.具体的内存分配方式
当使用new关键字创建一个类的对象时,虚拟机需要为新生对象分配内存空间,而对象的大小在类加载完成后已经确定了,所以分配内存只需要在Java堆中划分出一块大小相等的内存。在Java虚拟机中有指针碰撞和空闲列表两种方式分配内存。
2.1指针碰撞法
如果Java堆中内存是规整排列的,所有被用过的内存放一边,空闲的可用内存放一边,中间放置一个指针作为它们的分界点,在需要为新生对象分配内存的时候,只要将指针向空闲内存那边挪动一段与对象大小相等的距离即可分配。
2.2空闲列表法
如果Java堆中内存不是规整排列的,用过的内存和可用内存是相互交错的,这种情况下将不能使用指针碰撞方式分配内存,Java虚拟机需要维护一个列表用于记录哪些内存是可用的,在为新生对象分配内存的时候,在列表中寻找一块足够大的内存分配,并更新列表上的记录。
2.3Java虚拟机选择策略
Java虚拟机采用哪种方式为新生对象分配内存,取决于所使用的垃圾收集器,当垃圾收集器具有整理过程时,虚拟机将采用指针碰撞的方式;当垃圾收集器的回收过程没有整理过程时,则采用空闲列表方式。
3.小结
通过这篇文章,我们能够更加清楚的知道对象在堆中是如何分配的了,那两种具体的分配方式要掌握。