概述:java应用程序由java虚拟机自动管理程序执行期间内存管理。

优势:1、不再需要程序员去为使用的内存在程序中手动编写释放内存代码。

           2、由虚拟机管理内存不容易出现内存泄漏和内存溢出的问题。

缺点:一旦程序在执行过程中出现内存泄漏,排查错误将是一项“艰难"工作。

java虚拟机内存管理详解:

  java虚拟机将内存划分为以下区域:

  线程共享区:方法区(Method Area)/虚拟机堆(Heap)

       线程隔离或者说独占区:程序计数器(Program Counter Register)/虚拟机栈(VM Stack)/本地方法栈(Native Method Stack)

       

       线程私有的程序计数器区:

  功能:在JVM中,通过程序计数器来记录程序的字节码执行位置。程序计数器具有线程隔离性,每个线程拥有自己的程序计数器,程序在执行过程中,单个线程通过程序计数器区知道自己下一步需要执行哪条字节码指令,所以程序计数器里面记录是虚拟机字节码指令的地址,而不是字节码指令。

       线程私有的虚拟机栈区:

       功能:java方法执行的内存模型区域,每个方法在执行同时,都会创建一个私有的栈幀,栈幀中存放方法的局部变量表,操作数栈、动态链接、方法的return信息等,每一个方法从调用到执行完毕,就对应着每个栈幀在虚拟机栈中从入栈到出栈的整个过程。

       局部变量表:存放编译期间可知的各种基本数据类型,对象的引用(引用可以是指针、对象的句柄),句柄:系统为各个应用程序腾出一些内存地址,用来专门登记各个应用对象在内存中的地址变化,而这个地址(存储单元的位置)本身是不变的,这个地址就是句柄;指针:对象的在系统内存中的物理地址,这个地址可以随着系统重新创建对象而改变;句柄相比于指针更具有可靠性,但效率比直接使用对象的指针要慢,因为系统需要额外划出一块内存去存放句柄与对象地址的映射关系。

       线程私有的本地方法栈区:

       功能:为虚拟机使用到的native方法服务。

       

    线程间共享的虚拟机堆区:

       功能:在虚拟机启动时创建,存放对象实例。需要逻辑上堆内存空间连续,物理上可不连续。

       线程共享的虚拟机方法区:

       功能:存放已被虚拟机加载的类信息、常量、静态变量,编译器编译后的代码数据;方法区包括另一个区域:运行时常量池,运行时常量池具备动态添加数据能力。

即除编译期间可以存放常量外,运行期间如产生常量,也可放入常量池中。intern方法,这个方法是一个 native 的方法,但注释写的非常明了。“如果常量池中存在当前字符串, 就会直接返回当前字符串. 如果常量池中没有此字符串, 会将此字符串放入常量池中后, 再返回”。