运行时数据区域
主要包括:
- 线程私有:程序计数器(Program Counter Register)、虚拟机栈(VM Stack)、本地方法栈(Native Method Stack)
- 线程共享:堆(Heap)、方法区(Method Area)
程序计数器
代码执行的行号指示器,因为在Java虚拟机中其多线程是通过线程轮流切换并分配处理器执行时间来实现,为了保证某个线程切换后能够恢复到正确的执行位置,因此每个线程都有一个独立的程序计数器,所以其是私有的。
虚拟机栈
Java方法执行的内存模型,存储局部变量表、操作数栈、动态链接、方法出口等信息。
Java堆
Java虚拟机管理的内存中最大的一块区域,目的是存放对象的实例,在物理上可以不连续但在逻辑上要连续。
方法区
存储已被虚拟机加载的类信息、常量、静态常量等。
运行时常量池
方法区的一部分,存放编译期生成的各种字面量和符号引用。String判等典型题。
对象的创建
主要有两种方式:
- 指针碰撞(Bump the Pointer)
- 空闲列表(Free List)
指针碰撞
Java堆中的内存是绝对规整的,用过的内存放在一边,空闲的放在另外一边,中间存放一个指针作为分界点,分配内存就是把指针向空闲区域移动一段与对象大小相等的距离。
空闲列表
若Java堆中的内存不是规整的,空闲和已用的内存相互交错,虚拟机需要维护一个列表,记录哪些内存是可用的,分配时找到足够大的空间分配给对象,并更新列表。