在运行中,JVM分成5个部分,分别是方法区、堆、程序计数器、虚拟机栈、本地方法栈。
堆和方法区是代表了共享区,是所有线程都能访问到的地方。而程序计数器和虚拟机栈和本地方法栈是线程独有的部分,私有区包含程序计数器、虚拟机栈和本地方法栈。
-
堆:堆是Java虚拟机所管理的内存中最大的一块,也是最主要的一部分,它唯一的目的就是存放在程序运行时所创建的对象实例,堆是垃圾回收的主要区域,对于垃圾回收来说,主要是在堆中进行处理,对于那些不再被使用也就是没有持有引用的对象,Java的垃圾回收器在堆中对其进行回收及销毁。
-
方法区:方法区主要用于存储虚拟机加载的类的信息、常量、静态变量等数据,方法区也是被所有线程共享的,这里面的数据对于其他线程来说是开放的,可以进行直接访问的。对于存储在方法区的数据,Java的垃圾回收器很少对其进行垃圾回收,但是它也不是不回收,主要回收的内容是常量以及类型卸载的信息,对于常见的静态变量是不进行回收的,但是注意,如果我们定义的静态常量是一个引用类型的话,那么被引用的这个对象是有可能被回收的。
-
程序计数器:是指当前线程所执行的字节码指令的行号指示器,例如分支、跳转、循环、异常处理、线程恢复都需要依赖程序计数器来实现,在Java多线程是通过线程轮流切换来分配时间片来执行的,为了线程切换后能恢复到正确的位置,所以每个线程都有单独的程序计数器,所以程序计数器都是私有的。你只需要记住,当程序设计到分支、跳转的时候,它用计数器来记录行号,这是最典型的应用。
-
虚拟机栈:是每个线程私有的,在栈中主要为Java的方法服务。当线程创建的时候,虚拟机栈会为线程分配一块内存的区域,在线程执行的过程中,调用的每个方法都会创建一个栈帧,可以形象地把栈帧看成对当前方法的一个引用,在栈帧中用于存放局部变量,操作栈,动态链接,方法出口等。每个方法从被调用到被执行完,都对应着一个栈帧在虚拟机中从入栈到出栈的一个过程。可以形象的看成这个栈帧是当前方法在内存中的一个实例。
-
本地方法栈:和虚拟机栈非常相似,只不过用途有些区别,它们的主要区别是虚拟机栈是为执行Java方法时所提供的,存放执行Java方法的栈帧,而本地方法栈则是为执行本地方法时所服务的,用于在调用操作系统级别的底层方法时才会在这里面存放方法的栈帧。