文档章节

内存管理机制-内存模型与对象的访问

Garrry
 Garrry
发布于 2017/06/05 10:50
字数 1677
阅读 2
收藏 1

 

RoadMap

 

虚拟机中的逻辑结构

虚拟机中的内存结构根据虚拟机规范划分出了五个常用区域,这些区域各自有各自的用途,有些随用户线程而存在,有些则随虚拟机进程而存在。 
五个区域分别为,虚拟机栈,本地方法栈,程序计数器,堆,方法区

 

程序计数器 (Program Counter Register, PCR)

程序计数器是随线程而生的,它是线程独立的,用来记录当前线程的字节码与指令,保证下一次线程唤醒之后,能回到正确的执行位置,说白了就是线程唤醒能继续执行。 
程序计数器是一块非常小的内存区域,也是唯一一个没有规定任何OutOfMemoryError的区域

虚拟机栈 (Virtual Machine Stack, VM Stack)

虚拟机栈也是线程私有的,它描述了Java方法执行的内存模型:每个方法被执行是都会创建一个帧栈(Stack Frame) 用于存储 局部变量表 操作数栈 动态链接 方法出口。每一个方法被调用直至执行完成的过程,就是对应着一个帧栈在虚拟机栈中从入栈到出栈的过程。 
局部变量表存放了编译期可知的基本类型和引用类型。 
在这个区域中,虚拟机规范规定了两种异常情况,StackOverflowError:当线程请求栈的深度大于虚拟机允许的深度,将会抛出此异常。 OutOfMemoryErro:当虚拟机栈在动态扩展长度时,无法申请到足够内存时将会抛出此异常

本地方法栈 (Native Method Stack, NM Stack)

本地方法栈与虚拟机栈发挥的作用非常类似,主要是为本地方法服务,虚拟机栈是为Java 方法服务的。 有些虚拟机实现 如 HotSpot 已经将NM Stack 和VM Stack 合二为一了

 

堆 (Heap)

heap 是java 虚拟机管理的内存中最大的一块,也是线程共享的。在虚拟机启动时 自动创建。 
除了JIT编译和逃逸分析技术下的对象,绝大多数的对象实例和数组都在堆上分配。 
同时 堆也是 垃圾收集器(Garbage Collection)主要工作的区域。 
如果堆中没有可分配的内存空间会抛出OutOfMemoryError

方法区

方法区与堆一样 是线程共享的,用于存储常量,静态变量,加载的类信息,即时编译的代码数据块。虽说 虚拟机规范把方法区化为堆的一部分,它却又一个别名non-heap,有意把它和堆区分开了,有些地方也把这地方称为,永久代,主要是因为把GC收集扩展至这个区域了或者说用永久代来实现方法区的功能。 
当方法去无法满足内存分配需求时,将会抛出OutOfMemoryError 
方法去主要存有: 
*类信息 
*类变量 
*类型常量池 
*方法信息 
String常量池便是其中之一。

直接内存

直接内存(Direct Memory)并不是虚拟机运行时数据区的一部分,也不是Java 
虚拟机规范中定义的内存区域,但是这部分内存也被频繁地使用,而且也可能导致 
OutOfMemoryError 异常出现,所以我们放到这里一起讲解。 
在JDK 1.4 中新加入了NIO(New Input/Output)类,引入了一种基于通道(Channel) 
与缓冲区(Buffer)的I/O 方式,它可以使用Native 函数库直接分配堆外内存,然 
后通过一个存储在Java 堆里面的DirectByteBuffer 对象作为这块内存的引用进行 
操作。这样能在一些场景中显著提高性能,因为避免了在Java 堆和Native 堆中来 
回复制数据。

堆中的分代划分

heap 中内存划分基于分代思想 主要分为 新生代,老年代和存活区。 

新生代 Eden

大多数情况下,对象在新生代中分配。当Eden区没有足够的空间的时候会发起一次MinorGC

老年代 Old Generation

大对象直接进入老年代,所谓大对象就是指需要大量连续内存空间的Java 对象,如数组,字符串等。 
同时基于分代思想,虚拟机给每个对象定义了一个对象年龄。当对象在Eden区经过MinorGC后还生存下来后,会被移动到Suivior Space中并记为年龄为1,并且在Suivior Space 每经过一次GC后 对其中存活的对象年龄加1,当对象年龄超过一定的阈值(默认为15)时,将会被移动到老年代。

存活区 Suivivor Space

存活区有点像青年代,用于那些新生代存活下来而未到达老年代的对象。 
同时 存活区分为From,to 两块空间相同的区域,作为复制回收算法的区域

如果只是按照对象年龄阀值来判断是否需要移动到老年代,难以应付多变的内存情况,加入在存活区有着非常大量的年轻对象(2,3,4,5,6,7岁等)以至于 存活区内存不太够用的情况。对于这种情况,survivor有一个动态年龄判定。在存活区中的相同年龄的所有对象大小的总和大于Survivor空间的一半,年龄大于或等于该年龄的对象就直接进入老年代。

对象访问方式

Object obj = new Object() 
Object obj 声明了一个引用对象 
new Object() 在堆中开辟了空间并生成对象 
所谓对象的访问方式是指,引用类型obj如何定位到堆中的具体对象Object()的。

虚拟机中主流的方式有两种直接指针和句柄池

句柄池

如果使用句柄访问方式,堆中会划分出一小块内存作为句柄池,reference存储的是对象的句柄地址,而句柄中包含了对象实例数据和各自数据的具体地址信息。优点在于,reference存储的是稳定的句柄地址,在对象被移动时,只会改变句柄中的实例数据指针,reference本身不需要改变。 

直接指针

如果使用饿了直接指针访问,reference中直接存储了对象的地址。次方式的优点在于节约对象访问方式,对于频繁的访问对象,直接指针节约了一个层级的访问时间。 

© 著作权归作者所有

共有 人打赏支持
Garrry
粉丝 22
博文 46
码字总数 48703
作品 0
浦东
技术主管
私信 提问
Python内存管理机制

1 概述 对于Python这样的动态语言,如何高效的管理内存,是很重要的一部分,在很大程度上决定了Python的执行效率。与大多数编程语言不同,Python中的变量无需事先申明,变量无需指定类型,程...

guzhoujiexing
2014/05/03
0
0
JavaScript 内存机制(前端同学进阶必备)

简介 每种编程语言都有它的内存管理机制,比如简单的C有低级的内存管理基元,像,。同样我们在学习JavaScript的时候,很有必要了解JavaScript的内存管理机制。 JavaScript的内存管理机制是:内...

梁音
06/01
0
0
Android安全模型之介绍

从技术架构角度来看,Android安全模型基于强健的Linux操作系统内核安全性,通过进程沙箱机制隔离进程资源,并且辅以独特的内存管理技术与安全高效的进程间通信机制,适应嵌入式移动端处理器性...

柳哥
2014/11/30
0
0
JVM内存区域与多线程

Java并发的机制的背后是Java虚拟机(JVM)的工作机制,本文从几个关于并发和多线程的疑问开始,引出Java内存区域的介绍,希望能帮助大家更好的理解Java并发机制。 1. 线程创建和切换的代价—...

登高且赋
2017/12/08
0
0
Java 缓存框架--Imcache

Imcache是一个新的Java缓存库包,它支持各种已应用至今高速缓存模型。Imcache打算通过提供管理缓存数据的方法,以加快应用程序。它提供了从小型应用到大规模应用解决方案。 支持堆外off-hea...

欧德高
2014/01/24
1K
0

没有更多内容

加载失败,请刷新页面

加载更多

前端杂谈: 如何实现一个 Promise?

前端杂谈: 如何实现一个 Promise? 首先, 什么是 Promise? A promise is an object that may produce a single value some time in the future: either a resolved value, or a reason that i......

ssthouse_hust
14分钟前
1
0
Unsaft类

Unsafe类提供了硬件级别的原子操作,主要提供了以下功能 1、通过Unsafe类可以分配内存,可以释放内存; allocateMemory 分配内存 reallocateMemory 扩充内存 freeMemory 释放内存 2、可以定位...

器石_
15分钟前
1
0
git常用命令

首先打开git bash方式可以直接鼠标右击 或者在开始菜单(windows系统,苹果暂时不要问我,等我有钱买苹果电脑告诉你们0.0) 打开界面如下 1.查看远程仓库地址 git remote -v 2.创建本地分支 ...

熊小熊会写代码哦
26分钟前
2
0
离屏Canvas — 使用Web Worker提高你的Canvas运行速度

现在因为有了离屏Canvas,你可以不用在你的主线程中绘制图像了! Canvas 是一个非常受欢迎的表现方式,同时也是WebGL的入口。它能绘制图形,图片,展示动画,甚至是处理视频内容。它经常被用...

嫣然丫丫丫
28分钟前
2
0
SpringBoot 整合 BeetlSQL

SpringBoot 整合 BeetlSQL 1. beetlsql介绍 BeetSql是一个全功能DAO工具, 同时具有Hibernate 优点 & Mybatis优点功能,适用于承认以SQL为中心,同时又需求工具能自动能生成大量常用的SQL的应...

Jeff_Regan
28分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部