【JAVA】【JVM】内存结构
虽然jvm帮我们做了内存管理的工作,但是我们仍需要了解jvm到底做了什么,下面我们就一起去看一看
jvm启动时进行一系列的工作,其中一项就是开辟一块运行时内存。而这一块内存中又分为了五大区域,分别用于不同的功能。

程序计数器
记录程序运行的下一条指令的地址,这里的“地址”可以是一个本地指针,也可以是在方法字节码中相对于该方法起始指令的偏移量。如果该线程正在执行一个本地方法,那么此时程序计数器的值为”undefined”.在多线程环境下,每一个线程都有自己的程序计数器,在jvm调度线程时,会把当前的线程的程序计数器保存到快照,以便下次线程获取执行时间时获取
VM Stack
虚拟机栈是Java方法执行的内存模型,每个方法执行的时候,会在栈中创建一帧用于存储局部变量表、操作数栈、动态链接、方法出口。方法开始调用时,会创建栈帧并入栈,方法执行结束时会出栈。每个线程都有自己的栈。
动态链接:是一种在常量池中指向方法的符号引用,需要在运行期确定为直接引用
方法出口:当前执行方法的调用者的程序计数器,或异常处理表的地址
可以通过 -xxs 大小 来配置栈的大小,当嵌套调用使用不当,会导致方法不停的入栈,最终导致栈空间被占满产生 StackOverflowError
本地方法栈
Heap
堆是用于存放对象实例的地方,几乎所有对象实例在堆中分配。堆是线程共享的,这是多线程时同步机制的原因。
堆是GC管理的主要区域,GC在对堆进行回收前,首先要确定对象是否已死(不可能再被使用的对象)
判断对象是否存活的算法有两种:引用计数算法、可达性分析算法
引用计数算法是为每一个对象添加一个引用计数器,每当有一个引用指向它时,计数器就加一,任何时刻计数器为0的对象就不可能再被使用。这种算法实现简单,但是它很难解决对象循环引用的问题(何为循环引用见下方备注)
可达性分析算法是Java语言正在使用的算法。它的基本思想是通过一系统被称为“GC Root”的对象为起点,从这个起点向下搜索,搜索走过的路径称为引用链,当一个对象不再任何引用链上时,则说明这个对象是不可能再被使用的。
在Java语言中,GC Root包括以下几种对象:
- 虚拟机栈中引用的对象
- 本地方法栈中JNI引用的对象
- 方法区中类静态成员变量引用的对象
- 方法区中常量引用的对象
可以看出分析对象是否存活,都与引用有关。在JDK1.2之后,Java对引用的概念进行了扩充,将引用分为 强引用(Strong Reference)、软引用(Soft Reference)、弱引用(Weak Reference)、虚引用(Phantom Reference)
- 强引用
强引用即为原来意义上的引用,只要强引用存在,被引用的对象就不会被回收
- 软引用
SoftReference类表示软引用,对于被软引用关联的对象,在系统将要发生内存溢出时,会把这些对象列入回收范围后,进行二次回收
- 弱引用
WeakReference类表示弱引用,对于被弱引用关联的对象,只能生存到下一次垃圾回收发生之前
- 虚引用
PhantomReference类表示虚引用,虚引用不对关联的对象的生存时间构成影响,也无法取得对象实例,它唯一的作用是在对象被GC回收是收到一条系统通知
堆得大小可以通过-Xmx和-Xms来控制。对于主流的Jvm,GC基本都采用分代收集的算法。基于这个算法, Java堆又分为新生代(Young Generation)和老年代(Old Generation),新生代又被进一步划分为Eden和Survivor区,最后Survivor由FromSpace和ToSpace组成。新建的对象都是用新生代分配内存,Eden空间不足的时候,会把存活的对象转移到Survivor中,新生代大小可以由-Xmn来控制,也可以用-XX:SurvivorRatio来控制Eden和Survivor的比例。老生代用于存放新生代中经过多次垃圾回收(也即Minor GC)仍然存活的对象。
永生代(Permanent Space)为方法区

方法区
方法区也为所以线程所共享,用于存放已加载的类信息、静态变量、常量和即时编译器编译后的代码。-XX:MaxPermSize用于设置方法区大小
直接内存
直接内存不是虚拟机运行时数据区的一部分。通过Native函数库直接分配的堆外内存,然后通过存储在Java堆中的DirectByteBuffer对象作为这块内存的引用进行操作
【JAVA】【JVM】内存结构的更多相关文章
- JVM基础系列第6讲:Java 虚拟机内存结构
看到这里,我相信大家对于一个 Java 源文件是如何变成字节码文件,以及字节码文件的含义已经非常清楚了.那么接下来就是让 Java 虚拟机运行字节码文件,从而得出我们最终想要的结果了.在这个过程中,J ...
- 【JVM】JVM内存结构 VS Java内存模型 VS Java对象模型
原文:JVM内存结构 VS Java内存模型 VS Java对象模型 Java作为一种面向对象的,跨平台语言,其对象.内存等一直是比较难的知识点.而且很多概念的名称看起来又那么相似,很多人会傻傻分不清 ...
- 【转】JVM内存结构 VS Java内存模型 VS Java对象模型
JVM内存结构 我们都知道,Java代码是要运行在虚拟机上的,而虚拟机在执行Java程序的过程中会把所管理的内存划分为若干个不同的数据区域,这些区域都有各自的用途. 其中有些区域随着虚拟机进程的启动而 ...
- 简单说说 Java 的 JVM 内存结构
问:简单说说 Java 的 JVM 内存结构分为哪几个部分? 答:JVM 内存共分为虚拟机栈.堆.方法区.程序计数器.本地方法栈五个部分,分别解释如下.虚拟机栈:线程私有的,每个方法在执行时会创建一个 ...
- java的线程安全、单例模式、JVM内存结构等知识学习和整理
知其然,不知其所以然 !在技术的海洋里,前路漫漫,我一直在迷失着自我. 欢迎访问我的csdn博客,我们一同成长! "不管做什么,只要坚持下去就会看到不一样!在路上,不卑不亢!" 博 ...
- Java虚拟机(一):JVM内存结构
所有的Java开发人员可能会遇到这样的困惑?我该为堆内存设置多大空间呢?OutOfMemoryError的异常到底涉及到运行时数据的哪块区域?该怎么解决呢?其实如果你经常解决服务器性能问题,那么这些问 ...
- 【Java】JMM内存模型和JVM内存结构
JMM内存模型和JVM内存结构 JAVA内存模型(Java Memory Model) Java内存模型,一般指的是JDK 5 开始使用的新的内存模型,主要由JSR-133: JavaTM Memor ...
- JVM内存结构 VS Java内存模型 VS Java对象模型
前面几篇文章中, 系统的学习了下JVM内存结构.Java内存模型.Java对象模型, 但是发现自己还是对这三者的概念和区别比较模糊, 傻傻分不清楚.所以就有了这篇文章, 本文主要是对这三个技术点再做一 ...
- Java 内存模型和 JVM 内存结构真不是一回事
这两个概念估计有不少人会混淆,它们都可以说是 JVM 规范的一部分,但真不是一回事!它们描述和解决的是不同问题,简单来说, Java 内存模型,描述的是多线程允许的行为 JVM 内存结构,描述的是线程 ...
- JAVA内存模型与JVM内存结构
问题:什么事java内存模型? 首先呢不要答堆.栈.方法区.这是JVM的内存结构.下面阐述了JMM和JVM的区别和自己对JMM的见解 1.Java内存模型(JMM):即多线程相关的.定义了一个线程对另 ...
随机推荐
- IDEA安装热部署插件JRebel
首先说下热部署是什么意思吧,简单了说就是在我们对代码进行更改之后,不需要重启项目,重新编译一下就可以直接运行最新的代码的部署方式.既然是部署方式,项目启动部署的时候当然就会和正常情况下不一样啦~ JR ...
- 从源码分析 XtraBackup 的备份原理
MySQL物理备份工具,常用的有两个:MySQL Enterprise Backup 和 XtraBackup. 前者常用于MySQL企业版,后者常用于MySQL社区版.Percona Server ...
- Go语言核心36讲(Go语言实战与应用六)--学习笔记
28 | 条件变量sync.Cond (下) 问题 1:条件变量的Wait方法做了什么? 在了解了条件变量的使用方式之后,你可能会有这么几个疑问. 1.为什么先要锁定条件变量基于的互斥锁,才能调用它的 ...
- dos的基本命令
打开cmd的方式 开始+系统+命令提示符 Win键+R 输入cmd打开控制台(推荐使用) 在任意的文件夹下面,按住shift键+鼠标右键点击,在此处打开命令行窗口 资源管理器的地址栏前面加上cmd + ...
- [bzoj5415]归程
首先肯定要预处理出每一个点到1的最短路(别写spfa) 然后以海拔为边权,建一棵kruskal重构树 用倍增找到vi最后一个小于pi的祖先,然后在子树中取min(预处理) 1 #include< ...
- 语音合成论文翻译:2019_MelGAN: Generative Adversarial Networks for Conditional Waveform Synthesis
论文地址:MelGAN:条件波形合成的生成对抗网络 代码地址:https://github.com/descriptinc/melgan-neurips 音频实例:https://melgan-neu ...
- led汇编点灯
1. 汇编LED原理 为什么使用Cortex-A汇编 使用汇编初始化soc外设 使用汇编初始化DDR,I.MX不需要,因为它内部的96k ROM中存放了自己编写的启动代码,这些代码可以读取DDR配置信 ...
- mybatis-批量操作数据(list对象 )
在实际工作中老是忘记 传入的参数和数据库参数名称要一致还是与实体类型一致导致很多笑话发生. 那我还是做个记录吧! dao层: int addRemark(@Param("list" ...
- Nginx大厂面试需要掌握多少v1.21.3
概述 **本人博客网站 **IT小神 www.itxiaoshen.com Nginx官网 最新版本为1.21.3 Nginx (engine x) 是一个开源的.高性能的HTTP和反向代理web服务 ...
- c语言printf输出最前端字符不显示
原因:语法错误,和其它语言语法混用. printf("链表长度 : %d \n",length); printf("length is : %d \n",len ...