Java文件经过编译后会生成class字节码文件,运行程序时,字节码文件经过类加载器加载进内存。Java的内存空间主要划分为4个部分:方法区、堆、栈和本地方法栈。
栈(Stack):
用于存放方法中的局部变量,局部变量包括编译期基本数据类型(8个基本数据类型)、对象引用(地址指针)。每个方法的运行一定在栈中,因为方法在执行的同时会创建一个栈帧(Stack Frame)用于存储局部变量表、操作数栈、动态链接、方法出口等信息,因此,可以理解为每个栈是独立的,线程私有的,即线程安全。
堆(Heap):
凡是new出来的对象都是在堆中的,堆内存里的对象都有一个16进制的地址值,多线程共享。
因为是垃圾收集器管理的主要区域,也被成为“GC堆”,垃圾回收机制算法和JVM参数调优也是在这个区域中进行的。从内存回收角度来看堆可分为:新生代和老生代。从内存分配的角度看,线程共享的Java堆中可能划分出多个线程私有的分配缓冲区(Thread Local Allocation Buffer,TLAB)。无论怎么划分,都与存放内容无关,无论哪个区域,存储的都是对象实例,进一步的划分都是为了更好的回收内存,或者更快的分配内存。
方法区(Method Area):
与堆一样,是各个线程共享的内存区域,它用于存储已被虚拟机加载的类信息、常量、方法信息、静态变量、即时编译器编译后的代码等数据,也被称为永久区。
本地方法栈(Native Method Stack):
本地方法栈与栈作用类似,就是Java语言调用外部语言(C语言),使用native方法服务,与操作系统有关。例如在安卓开发中,安卓的应用层是JAVA API,而底层是C语言,JNI技术中可以使用Java语言去调用C语言实现结构调用执行,从而提高程序执行的效率。