JVM内存模型及内存管理

来源:互联网 发布:cf网络异常怎么解决 编辑:程序博客网 时间:2024/06/08 09:29

JVM内存管理

  • JVM内存管理
  • java虚拟机运行时数据区
  • 程序计数器
  • java虚拟机栈
  • java堆
  • 方法区
  • 对象的创建
  • 对象的访问定位
  • GC的主要方法

1 java虚拟机运行时数据区


java虚拟机运行时的数据区涉及方法区、虚拟机栈、本地方法栈、堆、程序计数器等。其中,虚拟机栈、本地方法栈、程序计数器为线程私有。方法区、堆为线程共享。

2 程序计数器

字节码解释器,通过改变计数器的值来选择下一条需要执行的指令。
java虚拟机的多线程是通过线程轮流切换并分配处理器的执行时间来实现的,一个确定时刻一个处理器只能执行一个线程的指令。因此,每一个线程需要一个私有的程序计数器,使得线程切换后能恢复到正确的执行位置。

3 java虚拟机栈

java方法执行的内存模型
主要包括局部变量表,局部表量表存放基本数据类型以及对象引用。
局部变量表所需的内存空间在编译期间完成分配,当进入一个方法时,需要多大空间是确定的,运行期间不会改变局部变量表的大小。
当线程请求的栈深度>虚拟机允许的深度。。。StackOverFlowError
扩展时无法申请内存。。。OutofMemoryError

4 java堆

java虚拟机管理的内存中最大的一块
被所有的线程共享,用于存放对象实例,所有的对象实例以及数组都需要在堆上分配。
java堆是垃圾收集器管理的主要区域,因此也被成为“GC堆”。
目前使用最广泛的是分代收集
java堆可以处于物理上不连续的内存空间中,但在逻辑上连续。

5 方法区

线程共享的内存区域,存储已被虚拟机加载的类信息、常量、静态变量以及即时编译器编译后的代码。
这个区域的垃圾回收主要是针对常量池的回收和对类型的卸载。

6 对象的创建

由所采用的垃圾收集器是否带有压缩整理功能将对象创建分为两类:

1、指针碰撞

堆内存绝对规整,用过的内存与空闲内存间放置一个指针作为分界点指示器,分配内存时,将指针向空闲端移动与该对象大小相同的距离。

2、空闲列表

已使用的内存与空闲内存相互交错。
维护一个表,记录已使用的区域和空闲区域,分配内存时,从列表中找出一块足够大的空间划分给该实例,并更新列表。

7 对象的访问定位

1、使用句柄

间接访问,reference中存储的是稳定的句柄地址,在对象移动时只会改变句柄中的实例数据指针,而reference本身不需要修改。

2、直接指针

访问速度更快,节省了一次指针定位的时间开销。

8 GC的主要方法

垃圾回收器要负责完成3项任务:分配内存,确保被引用对象的内存不被错误的回收以及回收不再被引用的对象的内存空间。
对于垃圾回收器来说,它使用有向图来记录和管理堆内存中的所有对象,通过有向图识别哪些对象是“可达的”(有引用变量引用它就是“可达的”),哪些对象是“不可达的”(没有引用变量引用就是“不可达的”),不可达的对象都是可以被垃圾回收的。

8.1 引用计数法

当对象被引用时,引用计数器+1,当引用被置为空或者离开作用域,计数器-1。但由于不能解决相互引用的问题,JVM并没有采用这种算法。

8.2 追踪回收法

从根节点便利对象的“引用图”,对遍历到的对象加标记,遍历结束,没有被标记的对象可以被回收。

8.3 压缩回收法

把堆中活动的对象移到堆中一端,相当于碎片整理。

8.4 复制回收算法

把堆分为大小相同的两块区域,每个时刻都只有其中一个区域工作。直到该区域被消耗完,中断程序的执行,将该区域中的活动对象以遍历的方式复制到另一个区域里,复制过程中是紧挨布置的,从而消除内存碎片。复制的过程结束后程序继续执行,直到该区域被使用完再按照同样的方式进行垃圾回收。

8.5 按代回收算法

把堆分为两个或者多个子堆,每一个子堆被视为一代,算法执行过程中,优先收集“年幼”的对象,如果一个对象多次扫描后仍存活,则将该对象移入高一级堆里,减少扫描次数。

原创粉丝点击