认识JVM的内存分配
当我们在JVM中运行一段程序代码,JVM初始运行的时候都会分配好Method Area(方法区)和Heap(堆),而JVM每遇到一个线程,就为其分配一个Program Counter Register(程序计数器), VM Stack(虚拟机栈)和Native Method Stack (本地方法栈),当线程终止时,三者(虚拟机栈,本地方法栈和程序计数器)所占用的内存空间也会被释放掉。
这也是为什么我把内存区域分为线程共享和非线程共享的原因,非线程共享的那三个区域的生命周期与所属线程相同,而线程共享的区域与JAVA程序运行的生命周期相同,所以这也是系统垃圾回收的场所只发生在线程共享的区域的原因。
a(申请新内存)-->b(eden区)
b--内存充足-->c(在eden直接分配)
b--第一次内存不足-->d(首次进行yong gc,YGC)
d--Eden内存活的对象复制到s1-->e(Survivor1,s1)
b--第二次内存不足-->f(再次进行YCC)
f--eden+s1复制到s2清理eden和s1-->ff(Survivor2,s2)
f--生存次数超过阈值的对象-->g(老年代)
g--老年代空间不足时-->h(进行full gc,FGC)
No.1 程序计数器
程序计数器是一块较小的内存区域,作用可以看做是当前线程执行的字节码的位置指示器。分支、循环、跳转、异常处理和线程恢复等基础功能都需要依赖这个计算器来完成。
No.2 虚拟机栈
虚拟机栈也叫栈内存,是在线程创建时创建,它的生命期是跟随线程的生命期,线程结束栈内存也就释放,对于栈来说不存在垃圾回收问题,只要线程一结束,该栈就释放了,所以不存在垃圾回收。
它所描述的是java方法执行的内存模型,每个方法执行的同时创建帧栈(Strack Frame)用于存储局部变量表(包含了对应的方法参数和局部变量),操作栈(Operand Stack,记录出栈、入栈的操作),动态链接、方法出口等信息,每个方法被调用直到执行完毕的过程,对应这帧栈在虚拟机栈的入栈和出栈的过程。
2.1、局部变量表
局部变量表存放了编译期可知的各种:
基本数据类型(boolean、byte、char、short、int、float、long、double)
对象的引用(reference类型,不等同于对象本身,根据不同的虚拟机实现,可能是一个指向对象起始地址的引用指针,也可能是一个代表对象的句柄或者其他与对象相关的位置)
returnAdress类型(指向下一条字节码指令的地址)
局部变量表所需的内存空间:在编译期间分配,运行期间不改变(大小固定)。
2.2、栈帧
栈帧是一个内存区块,是一个数据集,是一个有关方法(Method)和运行期数据的数据集,当一个方法 A 被调用时就产生了一个栈帧 F1,并被压入到栈中,A 方法又调用了 B 方法,于是产生栈帧 F2 也被压入栈,执行完毕后,先弹出 F2栈帧,再弹出 F1 栈帧,遵循“先进后出”原则。
No.3 堆
Heap(堆)是JVM的内存数据区。该区域是被所有线程共享的内存区域,在JVM启动时候创建,专门用来保存对象的实例。
在Heap中分配一定的内存来保存对象实例,实际上也只是保存对象实例的属性值,属性的类型和对象本身的类型标记等,并不保存对象的方法(以帧栈的形式保存在Stack中)。而对象实例在Heap中分配好以后,需要在Stack中保存一个4字节的Heap内存地址,用来定位该对象实例在Heap中的位置,便于找到该对象实例。
堆是线程共享的内存区域,在JVM启动时候创建,专门用来保存对象的实例。
java堆处于物理不连续的内存空间中,只要逻辑上连续即可。
垃圾回收的主要场所。
No.4 方法区
方法区存放了:
- 加载类的类定义数据
- 常量和静态变量
- JIT(即时编译器)编译后的代码
方法区也可以是内存不连续的区域组成的,并且可设置为固定大小,也可以设置为可扩展的
垃圾回收在这个区域会比较少出现,这个区域内存回收的目的主要针对常量池的回收和类的卸载。
No.5 运行时常量池(Runtime Constant Pool)
方法区内部有一个非常重要的区域,叫做运行时常量池(Runtime Constant Pool,简称 RCP)。
在字节码文件(Class文件)中,除了有类的版本、字段、方法、接口等相关信息描述外,还有常量池(Constant Pool Table)信息,用于存储编译器产生的字面量和符号引用。这部分内容在类被加载后,都会存储到方法区中的RCP。值得注意的是,运行时产生的新常量也可以被放入常量池中,比如 String 类中的 intern() 方法产生的常量。
常量池就是这个类型用到的常量的一个有序集合。包括直接常量(基本类型,String)和对其他类型、方法、字段的符号引用.例如:
- 类和接口的全限定名;
- 字段的名称和描述符;
- 方法和名称和描述符。
池中的数据和数组一样通过索引访问。由于常量池包含了一个类型所有的对其他类型、方法、字段的符号引用,所以常量池在Java的动态链接中起了核心作用.
No.6 本地方法栈
与VM Strack相似,VM Strack为JVM提供执行JAVA方法的服务,Native Method Stack则为JVM提供使用native 方法的服务。
No.7 直接内存区
直接内存区并不是JVM 管理的内存区域的一部分,而是其之外的。该区域也会在 Java 开发中使用到,并且存在导致内存溢出的隐患。如果你对 NIO 有所了解,可能会知道 NIO 是可以使用 Native Methods 来使用直接内存区的。
JVM内存区域可以分为线程共享和非线程共享两部分,
线程共享的有堆和方法区,非线程共享的有虚拟机栈,本地方法栈和程序计数器。
认识JVM的内存分配的更多相关文章
- JVM初探- 内存分配、GC原理与垃圾收集器
JVM初探- 内存分配.GC原理与垃圾收集器 标签 : JVM JVM内存的分配与回收大致可分为如下4个步骤: 何时分配 -> 怎样分配 -> 何时回收 -> 怎样回收. 除了在概念 ...
- JVM总结(二):JVM的内存分配策略
这节我们总结一下JVM中的内存分配策略.目录如下: 内存分配策略 对象优先在新生代Eden分配 大对象直接进入老年代 长期存活的对象将进入老年代 动态对象年龄判定 空间分配担保 内存分配策略 Java ...
- JVM的内存分配垃圾回收策略
之前看过<深入了解Java虚拟机>感觉容易忘,今天写一篇博客加深一下印象. JVM的内存分配和垃圾回收(GC)主要发生在Java堆中.而Java堆根据对象的存活时间可以分为新生代和老年代, ...
- 一夜搞懂 | JVM GC&内存分配
前言 本文已经收录到我的Github个人博客,欢迎大佬们光临寒舍: 我的GIthub博客 学习导图 一.为什么要学习GC&内存分配? 时代发展到现在,如今的内存动态分配与内存回收技术已经相当成 ...
- jvm的内存分配总结
最近看了周志明版本的<深入理解Java虚拟机>第一版和第二版,写的很好,收获很多,此处总结一下. jvm中内存划分: 如上图,一共分为五块,其中: 线程共享区域为: 1.java堆 ...
- JVM的内存分配与垃圾回收策略
自动内存管理机制主要解决了两个问题:给对象分配内存以及回收分配给对象的内存. >>垃圾回收的区域 前面的笔记中整理过虚拟机运行数据区,再看一下这个区域: 注意在这个Runtime Data ...
- 浅谈JVM与内存分配
一.程序内存分配 初始内存分配 当一个程序准备运行时,它首先向java虚拟机要内存,但是java虚拟机本身没有权限,它只能向操作系统申请内存,此时java虚拟机会拥有一个初始内存, 此处额外说明一下e ...
- jvm对象内存分配
一.jvm简单结构图 1.jvm内存对象分配整体流程: 1.类加载子系统和方法区 类加载子系统负责从文件系统或者网络中加载Class信息,加载的类信息存放于一块称为方法区的内存空间.除了类的信息外, ...
- 【面试必备】小伙伴栽在了JVM的内存分配策略。。。
周末有小伙伴留言说上周面试时被问到内存分配策略的问题,但回答的不够理想,小伙伴说之前公号里看过这一块的文章的,当时看时很清楚,也知道各个策略是干嘛的,但面试时脑子里清楚,心里很明白,但嘴里就是说不清楚 ...
随机推荐
- Mybatis的xml文件对大于号小于号的特殊处理!
当我们需要通过xml格式处理sql语句时,经常会用到< ,<=,>,>=等符号,但是很容易引起xml格式的错误,这样会导致后台将xml字符串转换为xml文档时报错,从而导致程序 ...
- 【ADO.NET--MVC】初学MVC(MVC入门)(1)
最近一直在学MVC,本来今天想开始做项目了,但是一下手才发现还有好多好多都不懂,虽然想照搬别人的模板,但是还是觉得很虚,这也不懂哪也不懂.看来学习一门技术断不是那么简单,只要随便套套模板,看看别人代码 ...
- win10下使用Linux命令
下载Cygwin安装包 官网下载地址:https://cygwin.com/install.html 执行下载好的安装程序 选择默认安装路径C:\cygwin64即可,可在C:\cygwin64\bi ...
- spring5 源码深度解析----- @Transactional注解的声明式事物介绍(100%理解事务)
面的几个章节已经分析了spring基于@AspectJ的源码,那么接下来我们分析一下Aop的另一个重要功能,事物管理. 事务的介绍 1.数据库事物特性 原子性多个数据库操作是不可分割的,只有所有的操作 ...
- 【MySQL】mysql5.7数据库的安装和配置
第一步:直接从官网下载安装包,.msi 可以直接点击安装..zip直接解压到目录,本人是C:\Program Files\MySQL\mysql-5.7 第二步:需要配置环境变量,我的电脑->属 ...
- 《Windows内核分析》专题-索引目录
该篇博客整理了<Windows内核分析>专题的各篇博文,方便查找. 一.保护模式 二.进程与线程 [Windows内核分析]KPCR结构体介绍 (CPU控制区 Processor Cont ...
- EasyExcel 轻松灵活读取Excel内容
写在前面 Java 后端程序员应该会遇到读取 Excel 信息到 DB 等相关需求,脑海中可能突然间想起 Apache POI 这个技术解决方案,但是当 Excel 的数据量非常大的时候,你也许发现, ...
- CVE-2019-0708(非蓝屏poc)远程桌面代码执行漏洞复现
玩了几天 刚回成都 玩电脑复现一下~ 内核漏洞原理暂时 没看懂 别问 ,问就是不懂 0x01 复现环境和Exp准备 漏洞影响范围 Windows 7 Windows Server 2008 R2 W ...
- DeCantor Expansion (逆康托展开)
Background\text{Background}Background The \text{The }The Listen&Say Test will be hold on May 11, ...
- NServiceBus+Saga开发分布式应用
前言 当你在处理异步消息时,每个单独的消息处理程序都是一个单独的handler,每个handler之间互不影响.这时如果一个消息依赖另一个消息的状态呢? 这时业务逻辑怎么处理? ...