基于jdk1.8,个人理解,如有错误,还请大佬们指正:
1. JVM
一个JVM实例对应一个进程(比如本地程序启动之后就是一个进程,main是主线程);
从进程角度:JVM进程中划分为共享的内存区和线程独占的栈区;共享内存区域划分为堆和方法区;每个线程对应自己的栈区,包括程序计数器、本地方法栈、虚拟机栈;【图一水印,图二来自百科】
从角色角度:堆、虚拟机栈、本地方法栈、程序计数器、方法区【深入理解java虚拟机】
备注1:方法区存放类信息与运行时常量池,class实例不在方法区【https://blog.csdn.net/qingtiantianqing/article/details/51405517,评论battle】
2. 线程、虚拟机栈与栈帧的包含关系:
一个线程拥有一个私有虚拟机栈以及自己的程序计数器PC;
一个虚拟机栈可以拥有多个栈帧;
一个栈帧对应一个方法的调用;
线程可以调用多个方法,每调用一个方法,就将方法信息以栈帧方式压栈。
3. 几个问题:
问:线程声明的对象放在哪?
答:堆;
问:提供一种简单的方法解决线程分配对象的冲突问题
答:TLAB,线程私有分配缓存区,但是还是在Eden区,其它线程也可以访问;【https://www.cnblogs.com/BlueStarWei/p/9358757.html】
问:除了可以分配在堆上,可以分配在其它地方吗,如何配置?
答:可以直接在栈上分配,不过需要做逃逸分析,不会逃逸的可以直接栈上分配;配置的话,需要开启逃逸分析(+DoEscapeAnalysis)和标量替换(+EliminateAllocations)的参数【https://www.cnblogs.com/BlueStarWei/p/9358757.html】
问:逃逸分析解释一下
答:分为全局逃逸、参数逃逸、无逃逸,无逃逸的对象分配比较自由,可以进行优化(比如锁消除、栈上分配);【https://blog.csdn.net/w372426096/article/details/80938788】
问:标量替换解释一下
答:对象是聚合量,聚合量由标量构成,将对象分解为一系列标量叫做标量替换;如果对象不需要整体访问,可以拆分为标量放在寄存区,从而节省内存空间;