程序计数器:代码流程控制(顺序,选择,循环);线程切换时标记当前线程执行位置。
Java虚拟机栈:存放局部变量,对象引用,每次方法调用的数据都是通过栈传递; 随着线程创建而创建,随着线程死亡而死亡。
本地方法栈:存放本地方法的局部变量,操作数栈等,与虚拟机栈类似。
堆:存放对象实例以及数组。垃圾收集器管理的主要区域。
对象都会首先在 Eden 区域分配,在一次新生代垃圾回收后,如果对象还存活,则会进入 s0 或者 s1,并且对象的年龄还会加 1(Eden 区->Survivor 区后对象的初始年龄变为 1),当它的年龄增加到一定程度(默认为 15 岁),就会被晋升到老年代中。
方法区:存储已被虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码
内存分配方式取决于GC收集器算法是 “标记 - 清除” ,还是“标记 - 整理 (压缩)”
内存分配并发问题:频繁创建对象,要保证线程安全。
- CAS + 失败重试 : 乐观锁(CAS):不加锁假设没有冲突,如果因为冲突失败就重试,直到成功。
- TLAB : 为每一个线程预先在 Eden 区分配一块儿内存,JVM 在给线程中的对象分配内存时,首先在 TLAB 分配,当对象大于 TLAB 中的剩余内存或 TLAB 的内存已用尽时,再采用上述的 CAS 进行内存分配