- 堆不是一种数据结构(什么结构都可以存放在堆中)
- 堆内存的大小是可以调节的。类加载器读取了类文件后,需要把类、方法、常变量放到堆内存中,保存所有引用类型的真实信息
- JVM堆被同一个JVM实例中的所有Java线程共享
- JVM堆通常由某种自动内存管理机制所管理这种机制叫做“垃圾回收”
- 应用通过堆存储数据(申请、回收、托管) allocate/de-allocate dynamic GC
结构
养老区 Tenure Generation Space
OutOfMemoryErro
(1)Java虚拟机的堆内存设置不够,可以通过参数-Xms、-Xmx来调整。
(2)代码中创建了大量大对象,并且长时间不能被垃圾收集器收集(存在被用)
永久代
永久存储区是一个常驻内存区域,用于存放JDK自身所携带的Class,Interface的元数据,也就是说它存储的是运行环境必须的类信息,被装载进此区域的数据是不会被垃圾回收器回收的,关闭JVM才会释放此区域所占用的内存。
java.lang.OutofMemorvError:PermGen space
是Java虚拟机对永久代Perm内存设置不够。一般出现这种情况,都是程序启动需要加载大量的第三方jar包。例如:在一个Tomcat下部署了太多的应用。或者大量动态反射生成的类不断被加载,最终导致Perm区被占满。
快速分配策略:TLAB Thread Local Allocation Buffer
堆区是线程共享区域,任何线程都可以访问到堆区中的共享数据,为避免多个线程操作同一地址,需要使用加锁等机制,进而影响分配速度,由于对象实例的创建在JVM中非常频繁,因此在并发环境下从堆区中划分内存空间是线程不安全的,所以,多线程同时分配内存时,使用TLAB可以避免一系列的非线程安全问题,同时还能够提升内存分配的吞吐量,因此我们可以将这种内存分配方式称之为快速分配策略。
从内存模型而不是垃圾收集的角度,对Eden区域继续进行划分,JVM为每个线程分配了一个私有缓存区域,它包含在Eden空间内。