先来张图:
线程共享:堆、方法区 注意:因为有了TLAB技术,堆内存并不是完完全全的线程共享,其eden区域中还是有一部分空间是分配给线程独享的。
线程独享:栈
常量存储在方法区的常量池
成员变量存储在堆中的对象里面,由垃圾回收器负责回收。
局部变量的数据存在于栈内存中。栈内存中的局部变量随着方法的消失而消失。
栈中用来存放一些原始数据类型的局部变量数据和对象的引用(String,数组.对象等等)但不存放对象内容
堆中存放使用new关键字创建的对象.
字符串是一个特殊包装类,其引用是存放在栈里的,而对象内容必须根据创建方式不同定(常量池和堆).有的是编译期就已经创建好,存放在字符串常量池中,而有的是运行时才被创建.使用new关键字,存放在堆中。
根据几步理解一下:
1.Java中对象的存储位置
String aa = new String();
new创建的对象存储在堆内存中;
aa这个局部变量存储在栈内存中;
2.Java中常量的存储位置
常量存放在常量池中,而常量池在堆内存中
3.Java中局部变量的存储位置
局部变量存放在栈内存中
4.Java中全局变量和Static常量的存储位置
存放在全局数据区内存中
5.java中static修饰的成员变量及参数存放位置
存放在代码段内存中
TLAB了解一下:
为了保证对象的内存分配过程中的线程安全性,HotSpot虚拟机提供了一种叫做TLAB(Thread Local Allocation Buffer:线程私有的分配缓冲区)的技术。
在线程初始化时,虚拟机会为每个线程分配一块TLAB空间,只给当前线程使用,当需要分配内存时,就在自己的空间上分配,这样就不存在竞争的情况,可以大大提升分配效率。所以,“堆是线程共享的内存区域”这句话并不完全正确,因为TLAB是堆内存的一部分,他在读取上确实是线程共享的,但是在内存分分配上,是线程独享的