Java 内存模型基本概念
2018-02-02 17:04
204 查看
一 根据 JVM 规范,JVM 内存共分为虚拟机栈、堆、方法区、程序计数器、本地方法栈五个部分
1、栈:用于存放运行时局部变量(基本数据类型和对象引用)、操作栈、动态链接、方法出口等数据信息。
虚拟机栈:每个线程有一个私有的栈,随着线程的创建而创建。栈帧:栈里面存着的是一种叫“栈帧”(Java方法执行的内存模型)模型,每个方法被执行时都会创建一个栈帧,当方法执行结束后这些变量所占有的内存将会自动释放。
每个线程都有自己独立的栈空间,不共享。
线程栈只存放基本数据类型和对象引用地址。
方法中局部变量在线程栈空间中。
栈的大小可以固定也可以动态扩展。
当栈调用深度大于JVM所允许的范围,会抛出StackOverflowError的错误,不过这个深度范围不是一个恒定的值。
本地方法栈:
Native方法服务。在HotSpot虚拟机中和Java虚拟机栈合二为一.
这部分主要与虚拟机用到的 Native 方法相关,一般情况下, Java 应用程序员并不需要关心这部分的内容.
PC 寄存器(程序计数器):
PC 寄存器,也叫程序计数器。JVM支持多个线程同时运行,每个线程都有自己的程序计数器。倘若当前执行的是 JVM 的方法,则该寄存器中保存- 当前执行指令的地址;倘若执行的是native 方法,则PC寄存器中为空。
2、堆(heap):用于存放对象实例,在虚拟机启动时创建,几乎所有的对象实例都在这里分配内存。堆 是被所有线程共享的一块内存区域,当对象不再使用时,该对象所占用的内存会被释放,该对象被销毁。
这一点在Java虚拟机规范中的描述是:所有的对象实例以及数组都要在堆上分配。堆又分为:新生代、和老年代(还有一个永久代PermGen,存在方法区中)
新生代:Young Generation,主要用来存放新生的对象。
老年代:Old Generation或者称作Tenured Generation,主要存放应用程序声明周期长的内存对象。
OutOfMemoryError:当申请不到空间时会抛出 OutOfMemoryError
3、方法区:(Method Area)与Java堆一样,是各个线程共享的内存区域,用于存储已被虚拟机加载的类信息、静态数据(static方法和static属性)、常量池(final)等,在虚拟机启动的时候就已经创建,并且在整个程序运行期间都存在。
虽然Java虚拟机规范把方法区描述为堆的一个逻辑部分,但是它却有一个别名叫做Non-Heap(非堆),目的应该是与Java堆区分开来。运行时常量池:方法区的一部分,用于存放各种字面量(interned strings)(如 字符串常量 和 符号引用(Symbols) 。
方法区内存模型规范的实现 :PermGen 和 Metaspace
永久代PermGen:并非 所有 JVM都存在 PermGen, 在 JDK 8 中 HotSpot PermGen 已经完全移除。
元空间Metaspace: JDK 8 HotSpot 中新增,Metaspace使用的是本地内存,而不是堆内存。
JDK 6 之前 字面量(interned strings)(如 字符串常量),符号引用(Symbols) 存在方法区 ( PermGen )中。
JDK 8中 HotSpot 字面量(interned strings)(如 字符串常量)由永久代转移到java heap中,符号引用(Symbols)转移到了native heap 。
二 对象访问
Java是面向对象的一种编程语言,那么如何通过引用来访问对象呢?一般有两种方式:1、通过句柄访问
2、直接指针
此种方式也是HotSpot虚拟机采用的方式。
三 、内存溢出
在JVM申请内存的过程中,会遇到无法申请到足够内存,从而导致内存溢出的情况。一般有以下几种情况:虚拟机栈和本地方法栈溢出
StackOverflowError: 线程请求的栈深度大于虚拟机所允许的最大深度(循环递归)
OutOfMemoryError: 虚拟机在扩展栈是无法申请到足够的内存空间,一般可以通过不停地创建线程引起此种情况
Java堆溢出: 当创建大量对象并且对象生命周期都很长的情况下,会引发OutOfMemoryError
运行时常量区溢出:OutOfMemoryError:PermGen space,这里一个典型的例子就是String的intern方法,当大量字符串使用intern时,会触发此内存溢出
方法区溢出:方法区存放Class等元数据信息,如果产生大量的类(使用cglib),那么就会引发此内存溢出,OutOfMemoryError:PermGen space,在使用Hibernate等框架时会容易引起此种情况。
相关文章推荐
- Java 内存模型[部分概念,详细查阅书籍]
- Java多线程笔记一(创建运行,相关概念,JVM内存模型,线程有几种状态,死锁)
- java学习之旅52--数组_数组基本概念_内存分析
- Java并发编程:volatile关键字解析(一.内存模型的相关概念)
- JVM启动流程, JVM基本结构 ,内存模型,编译和解释运行的概念
- Java数组(Array)_基本概念_内存分析
- JVM 内存分配模型概念和java中各种对象的存储
- JVM 内存分配模型概念和java中各种对象的存储
- Java千百问_01基本概念(017)_内存物理地址在CPU中如何形成
- Java中的基本数据类型和引用数据类型的内存模型
- 【Java并发编程】6、volatile关键字解析&内存模型&并发编程中三概念
- Java内存分析(1) 基本概念说明
- java 并发概念与内存分析,原子性、可见性、有序性
- ANT的基本概念:Java的Makefile
- Java学习之内存的基本结构
- Java之内存模型
- 进程间通信系列(12)共享内存的基本概念
- Java 内存模型
- java 虚拟机内存模型
- Java数据结构与算法之数据结构-逻辑结构-线性结构(9)------Java线性结构概念及其基本操作