JVM(一)-内存结构

我们都知道,我们写的Java程序需要先经过编译,生成了.class文件(字节码文件)。然而,计算机并不能直接解释.class文件里面的内容,这时候就需要一个能加载、解释.class文件并且能按.class文件里的内容进行处理的一个东西--JVM。
JVM,就是Java虚拟机。它是一种规范,有针对不同系统的特定实现(Linux,Windows,macOS)。这样,相同的字节码就能在不同的系统上运行,实现了跨平台运行(Write Once, Run Anywhere)。
JVM的内存结构

上图是JDK1.8的JVM内存结构,可以看出内存结构分为程序计数器、Java虚拟机栈、本地方法栈、堆、元空间,其中程序计数器、Java虚拟机栈、本地方法栈是线程独享的(按线程隔离),其生命周期和所在线程相同,而堆、元空间是线程共享的。
程序计数器
程序计数器是一块较小的内存空间,可以看作是当前线程所执行的字节码的行号指示器。字节码解释器工作时通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等功能都需要依赖这个计数器来完成。
注意:程序计数器是唯一一个不会出现 OutOfMemoryError 的内存区域,它的生命周期随着线程的创建而创建,随着线程的结束而死亡。
Java虚拟机栈
每个Java方法在执行时都会创建一个栈帧(Java方法执行的内存模型)。每一个方法从被调用到执行完成的过程,就是一个栈帧在Java虚拟机栈中入栈到出栈的过程。栈是先进后出的数据结构,也就是说,后被调用的Java方法会先结束。

上图就是一个Java虚拟机栈的结构,一个Java虚拟机栈是由一个个栈帧组成的,而每个栈帧中都拥有局部变量表、操作数栈、动态链接、方法返回地址。
Java虚拟机栈可能会出现以下两种错误:
StackOverFlowError:若栈的内存大小不允许动态扩展,那么当线程请求栈的深度超过当前Java虚拟机栈的最大深度的时候,就抛出StackOverFlowError错误。
OutOfMemoryError:如果栈的内存大小可以动态扩展,如果虚拟机在动态扩展栈时无法申请到足够的内存空间,则抛出OutOfMemoryError异常。
局部变量表
主要存放了编译期可知的各种数据类型(boolean、byte、char、short、int、float、long、double)、对象引用(reference 类型,它不同于对象本身,可能是一个指向对象起始地址的引用指针,也可能是指向一个代表对象的句柄或其他与此对象相关的位置)。
操作数栈
主要作为方法调用的中转站使用,用于存放方法执行过程中产生的中间计算结果。另外,计算过程中产生的临时变量也会放在操作数栈中。
动态链接
主要服务一个方法需要调用其他方法的场景。在 Java 源文件被编译成字节码文件时,所有的变量和方法引用都作为符号引用(Symbilic Reference)保存在 Class 文件的常量池里。当一个方法要调用其他方法,需要将常量池中指向方法的符号引用转化为其在内存地址中的直接引用。动态链接的作用就是为了将符号引用转换为调用方法的内存地址的直接引用。

本地方法栈
本地方法栈与Java虚拟机栈作用相似,它们之间的区别是Java虚拟机栈为虚拟机执行Java方法服务,而本地方法栈则为虚拟机使用到的Native方法服务。本地方法被执行的时候,在本地方法栈也会创建一个栈帧,用于存放该本地方法的局部变量表、操作数栈、动态链接、方法返回地址。
堆
堆是Java虚拟机所管理的内存中最大的一块。Java堆是被所有线程共享的一块内存区域,在虚拟机启动时创建。堆的作用就是存放对象实例,几乎所有对象实例都在这个区域分配内存。
Java堆是垃圾收集器管理的主要区域,因此也叫GC堆(Garbage Collected Heap)。从内存回收的角度(收集器一般采用分代收集算法),Java堆内存可以细分为:新生代和老年代。新生代再细分有:Eden区、Survivor0区、Survivor1区。

根据虚拟机规范,Java堆可以处于物理上的不连续内存中,只要逻辑上是连续即可。其大小可以通过-Xmx和-Xms控制。如果在堆中没有内存完成实例分配,并且堆也无法扩展时会抛出OutOfMemoryError异常。
方法区

虚拟机要使用一个类时,它需要读取并解析.class文件获取相关信息,再将信息存入到方法区。方法区用于存放类信息、字段信息、方法信息、常量、静态变量、即时编译器编译后的代码缓存等数据。
《Java 虚拟机规范》只是定义了方法区这个概念和它的作用,在不同的虚拟机实现上,方法区的实现是不同的。JDK1.8之前的方法区实现叫永久代,到了JDK1.8,方法区实现叫元空间,它取代了永久代。元空间与永久代之间最大的区别在于:元空间并不在虚拟机中,而是使用本地内存。因此,默认情况下,元空间的大小仅受本地内存限制。

元空间 (MetaSpace)替代永久代(PermGen) 的原因如下:
1、永久代受到JVM本身设置的固定大小限制,无法进行调整,而元空间使用的是直接内存,受本机可用内存的限制,虽然元空间仍旧可能溢出,但是比永久代出现的几率会更小。
2、永久代的对象是通过FullGC进行垃圾收集,也就是和老年代同时实现垃圾收集。替换成元空间以后,简化了Full GC。可以在不进行暂停的情况下并发地释放类数据,同时也提升了GC的性能。
3、在JDK1.8,合并HotSpot和JRockit的代码时, JRockit从来没有一个叫永久代的东西, 合并之后就没有必要额外的设置这么一个永久代的地方了。
JVM(一)-内存结构的更多相关文章
- 巩固java(二)----JVM堆内存结构及垃圾回收机制
前言: 我们在运行程序时,有时会碰到内存溢出(OutOfMemoryError)的问题,为了解决这种问题,我们有必要了解JVM的内存结构和垃圾回收机制. 正文: 1.JVM堆内存结构 ...
- JVM的内存结构,JVM的回收机制
内存作为系统中重要的资源,对于系统稳定运行和高效运行起到了关键的作用,Java和C之类的语言不同,不需要开发人员来分配内存和回收内存,而是由JVM来管理对象内存的分配以及对象内存的回收(又称为垃圾回收 ...
- JVM 垃圾回收机制和常见算法和 JVM 的内存结构和内存分配(面试题)
一.JVM 垃圾回收机制和常见算法 Sun 公司只定义了垃圾回收机制规则而不局限于其实现算法,因此不同厂商生产的虚拟机采用的算法也不尽相同.GC(Garbage Collector)在回收对象前首先必 ...
- JVM之内存结构详解
对于开发人员来说,如果不了解Java的JVM,那真的是很难写得一手好代码,很难查得一手好bug.同时,JVM也是面试环节的中重灾区.今天开始,<JVM详解>系列开启,带大家深入了解JVM相 ...
- JVM的内存结构以及性能调优
JVM的内存结构以及性能调优 发布时间: 2017-11-22 阅读数: 16675 JVM的内存结构以及性能调优1:JVM的结构主要包括三部分,堆,栈,非堆内存(方法区,驻留字符串)堆上面存储的是引 ...
- JVM的基本结构和JVM的内存结构
这里概要介绍一下JVM在启动后,作为操作系统的一个进程的基本结构,以及从操作系统角度看,JVM如何管理它从操作系统里申请来的内存的,也就是JVM的内存结构或者叫JVM内存模型. 1.JVM的基本结构 ...
- JVM:内存结构
JVM:内存结构 说明:这是看了 bilibili 上 黑马程序员 的课程 JVM完整教程 后做的笔记 内容 程序计数器 虚拟机栈 本地方法栈 堆 方法区 直接内存 1. 程序计数器 1.1 定义 P ...
- JVM之内存结构
JVM是按照运行时数据的存储结构来划分内存结构的.JVM在运行Java程序时,将他们划分成不同格式的数据,分别存储在不同的区域,这些数据就是运行时数据.运行时数据区域包括堆,方法区,运行时常量池,程序 ...
- Java中的JVM的内存结构
Java的虚拟机自身结构图: JVM内存结构主要包括两个子系统和两个组件.两个子系统分别是Classloader子系统和Executionengine(执行引擎)子系统:两个组件分别是Runtimed ...
- JVM(一) 内存结构
JVM内存结构 方法区(JDK8以上叫元空间)和堆为线程共享区,虚拟机栈.本地方法栈及程序计数器为线程独占区, 还有一个没有在下图中体现的叫做直接内存(Direct Memory),不受JVM GC ...
随机推荐
- NetCat 工具的常用使用技巧
netcat 黑客们的瑞士军刀,虽然小巧但是其功能一点也不弱,并且该工具天生免杀,值得你去尝试. NCwindows反弹 1:正向连接 服务器执行:nc -l -p 8888 -e cmd.exe 本 ...
- ChatGPT 火了,一大批开源平替也来了
ChatGPT 凭一己之力让全球为 AI 沸腾,引发了科技巨头之间的聊天机器人军备竞赛. 众所周知,ChatGPT 的背后技术是 GPT(Generative Pre-trained Transf ...
- 分享实用小工具:JAVA版本位运算工具类
将二进制数中的每位数字1或0代表着某种开关标记,1为是,0为否,则一个数字可以代表N位的开关标记值,可有效减少过多的变量定义 或 过多的表字段,同时也能在一些复杂的组合判断场景下利用位与.位或.异或等 ...
- Java 将PDF转为PowerPoint (2行代码)
通过编程实现PDF转PPT的功能,可以自动化转换过程,减少手动操作的工作量,并根据需要进行批量转换.将PDF文件转换为PPT文档后,可以利用PPT的丰富功能和动画效果,达到更好的演示效果. 在Java ...
- typescript 实现enum枚举值定义为对象
壹 ❀ 引 最近因为有一些闲散时间,所以一直在做将Class组件重构为typescript + hooks组件的工作,结果今天就遇到一个有趣的问题.我们知道react Class组件一般都会定义Com ...
- JS leetcode 宝石与石头 题解分析,正则字符组也有妙用
壹 ❀ 引 简单问题简单做,今天的题目来自leetcode771. 宝石与石头,字符串相关的一道题,题目描述如下: 给定字符串J 代表石头中宝石的类型,和字符串 S代表你拥有的石头. S 中每个字符代 ...
- Android自动化测试框架uiautomator2详解
1 uiautomator2 简介 uiautomator2 是 一种 Android 自动化测试框架,提供了点击.长按.输入文本.滑动.拖拽.截屏等方法,能够模拟用户的各种动作.用户可以通过控件 ...
- Vue中数组变动监听
Vue中数组变动监听 Vue的通过数据劫持的方式实现数据的双向绑定,即使用Object.defineProperty()来实现对属性的劫持,但是Object.defineProperty()中的set ...
- queryset高级用法:select_related
在提取某个模型的数据的同时,也提前将相关联的数据提取出来.比如提取文章数据,可以使用select_related将author信息提取出来,以后再次使用article.author的时候就不需要再次去 ...
- postgresql表结构查询sql
数据库表结构查询sql SELECT t1.attnum as "序号", t1.attname as "字段名", concat_ws ( '', t2.ty ...