JVM内存管理

一. jvm内存的划分?
1.方法区:存放 常量 静态变量 JIT(即时编译器)编译后的代码也在方法区存放, 方法区是线程共享的区域。
2.堆内存: 存放创建的对象(new) 垃圾回收的主要场地,也是线程共享的。
3.java虚拟机栈(栈内存) 存储局部变量 ,基本数据类型以及堆内存中对象的引用变量。
4.本地方发栈(c栈):为JVM提供使用native方法的服务。
5.程序计数器: 当前线程执行的字节码的位置指示器。
二. 下面详细的介绍一下上面的五个部分:
1.方法区:
定义:java虚拟机规范中定义的方法区是堆内存的一个逻辑部分,方法区存放以下的信息,已被虚拟机加载的类的信息, 常量,静态变量 即时编译后的代码。
特点:
01.线程共享:方法区是堆逻辑的一部分,因此跟堆一样,都是线程共享的,整个虚拟机中只有一个方法区。
02.永久代 方法区中的信息一般需要长期存在,而且他又是堆区的一部分,因此用堆的划分方法,把方法区成称为“永久代”。
03.内存回收效率低 方法区中的信息一般需要长时间存在,回收一遍只有少量的信息无效,主要回收的目标是:对常量池的回收;对类型的卸载。
04.java虚拟机规范对方法区的要求比较宽松,核对一样,允许固定大小,也允许动态扩展,还允许不实现垃圾回收。
运行时的常量:
方法区区中存放的:类信息,常量,静态变量,即时编译器编译后的代码。常量就存在运行时的常量池中,当类被java虚拟机加载后,.class文件中的常量就存在方法区的常量池中,而且在运行期间,可以向常量池中添加新的常量,如String类的intern()方法就能在运行期间向常量池中添加字符串常量。
2.堆内存:
定义:堆是用来存储对象的内存空间,几乎所有的对象都存储在堆中。
特点:
01.线程共享,整个java虚拟机只有一个堆,所有线程访问同一个堆
02.在虚拟机启动的时候创建的
03.是垃圾回收器的主要场所。
04.今一步可分为:新生代(Eden区 Form Survior To Surviror ) 老年代。
05.不同的区域存放的不同的生命周期的对象,这样可以根据不同区域的垃圾回收算法,更具有针对性。堆的大小也可以固定也可以扩展,对于主流的虚拟机,对大小可以扩展的,因此当县城的请求分配的内存,但堆内存已满,切并且内存已无法扩展的时候,就抛出OutOfMemoryErrory异常。
3.java虚拟机栈
定义:描述java方法运行过程的内存模型
java虚拟机会为每一个即将运行的java方法创建一块叫做“栈帧”的区域,用于存放在方法运行过程中的一些信息,局部变量表, 操作数,动态链接 方法出口信息
压栈出栈的过程:
当方法运行的过程中需要局部变量的时候,就将局部变量的值存入栈帧的局部变量表中。
由于java虚拟机栈是线程对应的,数据不是共享的,因此不用关心数据一致性问题,也不会存在同步锁的问题。
特点:
01.局部变量表随着栈帧的创建而创建,它的大小在编译时确定,创建时值需要分配实现规定的大小即可,在方法运行的过程中,局部变化标的大小不会发生变化
02.java虚拟机栈会抛出两种异常:StackOverFlowError和OutOfMemoryError
03.StackOverFlowError若Java虚拟机栈的大小不允许动态的扩展,那么当前的县城请求的栈的深度超过当前的java虚拟机栈的最大深度时,就会抛出这个异常。
04.OutOfMemoryError 若允许动态地扩展,那么当线程的请求的站的内存用完了,无法再动态扩展的时候,抛出的这个异常。
java虚拟机栈是线程私有的,随着线程的创建而创建,随着线程的结束而销毁。
4.本地方法栈(c栈)
定义:是为了jvm运行native方法准备的空间,有与很多方法都是用C语言实现的,所以通常又叫做C栈,它与java虚拟机栈实现的功类似,只不过本地方法栈描述的本地方法运行过程的内存模型。
4.程序技术器(PC计数器):
程序计数器的定义:程序计数器是一块较小的内存空间,是当前线程正在执行的哪一条字节码指令的地址,若当前线程正在执行的是一个本地方法,那么程序计数器为Undefined。

你可能感兴趣的:(JVM内存管理)