栈是线程私有的,每个线程都是自己的栈,每个线程中的每个方法在执行的同时会创建一个栈帧用于存局部变量表、操作数栈、动态链接、方法返回地址等信息。每一个方法从调用到执行完毕的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。其中局部变量表,存放基本类型(boolean、byte、char、short、int、float)、对象的引用等等,对象的引用不是对象实例本身,而是指向对象实例的一个指针。
堆是线程共享的,所有的对象的实例和数组都存放在堆中,任何线程都可以访问。Java的垃圾自动回收机制就是运用这个区域的。
方法区也是线程共享的,用于存放类信息(包括类的名称、方法信息、字段信息)、常量、静态变量以及即时编译器编译后的代码等等。
这么讲比较抽象,写段代码:
当程序执行到箭头指向那一个行代码的时候,入参i和局部变量j都是基本类型,直接存放在栈中。入参str和oneMoreStudy是对象类型,在栈中只存放对象的引用。如下图: