java内存模型
主存与工作内存
java内存模型将内存分为两部分:主存和工作内存。前者是所有线程共享的,而后者是每个线程独有的。
主存
主存包括方法区和堆
方法区
方法区用于存储已被虚拟机加载的类型信息、常量、静态变量、即时编译器编译后的代码缓存等数据
java堆
java堆的唯一目的即是存储java对象
根据对象的大小、存活时间可以利用分代技术划分为新生代和老年代(利于利用分代技术的垃圾回收器进行内存回收)。在垃圾回收机制中,新生代回收的频率更高,而老年代因为其本身特性(每次回收并不会回收太多东西,但是会消耗大量计算机资源,显得性价比不高)回收频率比新生代低很多。
新生代
新生代中有三个内存区域:
- eden伊甸园
- to_survivor
- from_survivor
其中Eden用于新的小对象的生成。而后两者则是为了标记-复制技术而才用的大小相同的内存区域。
标记-复制技术简单说明
当进行内存清理时,对eden和from_survivor中的对象进行可达性分析,如果是可达的则可以存活,于是将他们复制到to_survivor中,然后清空from_survivor和eden中的所有对象。如果to_survivor中的空间不足以存放,则会使用“老年担保”,将多余的对象移到老年代进行存储。
eden和survivor的大小比约为4:1。这样的大小分配是由实践数据计算得来的。
老年代
老年代中存储大对象以及在多次垃圾清理中存活下来的对象。
老化
当一个对象存活了多次垃圾回收,我们会将它移入老年代
其背后原理是,如果一个对象在多次垃圾回收后仍然存活,我们可以用以往数据预测未来,认为他在未来的垃圾回收中被回收的概率也不高,因此没有必要将它存放在新生代中占用资源。
新生代和老年代的划分并不是一定的,只有在利用分代技术的垃圾回收器中才有意义。对于一些不分代(比如使用region的ZGC)而言是没有这样的划分的
工作内存
//todo
并发编程中的三个概念
//todo
volatile关键字
//todo