java程序在运行过程各个内部结构的作用

一:内部结构

一个进程对应一个jvm实例,一个运行时数据区,又包含多个线程,这些线程共享了方法区和堆,每个线程包含了程序计数器、本地方法栈和虚拟机栈接下来我们通过一个示意图介绍一下这个空间。

如图所示,当一个helloword程序编译成为可以运行的二进制编码程序helloword.class程序的时候,运行二进制文件,整个进程会放到一个本地电脑的内存环境中去,其中,一个程序就是一个JVM实例,代码中包含定义方法的方法区域,开辟空间的堆空间区域,以及控制好程序的运行走向的程序计数器,以及方法调用时候用到的本地方法栈,虚拟机栈等,在代码运行的过程中我们知道代码会产生很多的垃圾,这些垃圾是需要JVM中的垃圾回收器去回收的她不像C或CPP那样手动的垃圾清除,在JAVA中一个JVM空间会有一个GC垃圾回收器,通过各种有效的算法帮我们实现垃圾的自动清除,后面我会介绍GC如何实现垃圾回收机制的。

二:程序计数器

程序计数器是什么?相信大家第一次听到这个话题的时候应该很敏感,其实博主是嵌入式转JAVA的所以对于底层还是颇有了解的。

  • 程序计数器是一块较小的内存空间,它可以看作是:保存当前线程所正在执行的字节码指令的地址(行号),简单来说就是记住我现在是哪个线程在具体的运行,保存一下

  • 由于Java虚拟机的多线程是通过线程轮流切换并分配处理器执行时间的方式来实现的,一个处理器都只会执行一条线程中的指令。(这里我来说明一下如下图所示,线程轮转简单来说就是时间片轮转,因为对于单核处理器而言,处理并发线程,就是在分配时间片给到每个并发线程不停地切换任务,所以所谓的并发并不是真的同时进行,只是无限接近并发而已,但是我要说明一下时间片轮转速度是非常快的,很多人疑问这个轮转速度是由什么保证的呢?----这就要考虑到硬件支持了,博主也是电子专业对其有一些了解,下次我再给你们介绍,现在画个饼哈哈哈)因此,为了线程切换后能恢复到正确的执行位置,每条线程都有一个独立的程序计数器,各个线程之间计数器互不影响,独立存储(如图所示,程序计数器及记录着每个线程运行到哪了,这样下次时间片轮转再次轮到你,你可以接着运行),称之为“线程私有”的内存。程序计数器内存区域是虚拟机中唯一没有规定OutOfMemoryError情况的区域。

不知道通过上面的例子大家有没有理解,不理解的话我下面举个例子:

线程A在看直播,突然,线程B来了一个视频电话,就会抢夺线程A的时间片,就会打断了线程A,线程A就会接电话,然后,视频电话结束,这时线程A究竟该干什么? (线程是最小的执行单位,他不具备记忆功能,他只负责去干,那这个记忆就由:程序计数器来记录)这样视频电话结束了以后又可以回到直播继续播放

三:栈

  1. java虚拟机是线程私有的,它的生命周期和线程相同

  2. 虚拟机栈描述的是Java方法执行的内存模型:每个方法在执行的同时都会创建一个栈帧(Stack Frame)用于存储局部变量表、操作数栈、动态链接、方法出口等信息

  3. 如图所示,其中每个栈信息的属性解释

  • 局部变量表:是用来存储我们临时8个基本数据类型、对象引用地址、returnAddress类型(returnAddress中保存的是return后要执行的字节码的指令地址)

  • 操作数栈:操作数栈就是用来操作的,例如代码中有个 i = 6*6,他在一开始的时候就会进行操作,读取我们的代码,进行计算后再放入局部变量表中去

  • 动态链接:假如我方法中,有个 service.add()方法,要链接到别的方法中去,这就是动态链接,存储链接的地方意思就是要在方法中转化到另外一个方法中去,这样就需要动态衔接

  • 出口:出口是什呢,出口正常的话就是return 不正常的话就是抛出异常落

如何设置栈的内存大小?

使用参数-Xss选项来设置线程的最大栈空间,栈的大小直接决定了函数调用的最大可达深度。 (IDEA设置方法:Run-EditConfigurations-VM options 填入指定栈的大小-Xss256k)

思考:

一个方法调用另一个方法,会创建很多栈帧吗?

答:会创建。如果一个栈中有动态链接调用别的方法,就会去创建新的栈帧,栈中是由顺序的,一个栈帧调用另一个栈帧,另一个栈帧就会排在调用者下面

栈指向堆是什么意思?

栈指向堆是什么意思,就是栈中要使用成员变量怎么办,栈中不会存储成员变量,只会存储一个应用地址,堆中的数据等下讲

递归的调用自己会创建很多栈帧吗?

递归的话也会创建多个栈帧,就是一直排下去,沒有結束条件就会产生oostack的风险,下面的例子就是爆栈的实际例子:

public class StackOverFlowErrorTest {public static void main(String[] args) {//递归调用mainmain(args);}
}

四:堆

  • java堆是java虚拟机所管理的内存中最大的一块,是被所有线程共享的一块内存区域,在虚拟机启动时创建,此内存区域的唯一目的就是存放对象实例

  • 在Java虚拟机规范中的描述是:所有的对象实例以及数组都要在堆上分配

  • java堆是垃圾收集器管理的主要区域,因此也被称为“GC堆”(后面在说GC垃圾回收机制的时候你就会明白这个名词)

  • 从内存回收角度来看java堆可分为:新生代和老生代

  • 从内存分配的角度看,线程共享的Java堆中可能划分出多个线程私有的分配缓冲区。

  • 无论怎么划分,都与存放内容无关,无论哪个区域,存储的都是对象实例,进一步的划分都是为了更好的回收内存,或者更快的分配内存(其实都在堆区域,只不过为了加快回收算法就细化了一些区域,毕竟堆空间区域很大)

  • 根据Java虚拟机规范的规定,java堆可以处于物理上不连续的内存空间中(正因为这个不连续性所以我们堆空间的位置都需要一个指针去维护它,不然很容易丢失,导致堆空间无法释放,内存泄漏)。当前主流的虚拟机都是可扩展的(通过 -Xmx 和 -Xms 控制)。如果堆中没有内存可以完成实例分配,并且堆也无法再扩展时,将会抛出OutOfMemoryError异常

堆的细分内存结构

一类是生命周期较短的瞬时对象,这类对象的创建和消亡都非常迅速(存入新生代)

另外一类对象时生命周期非常长,在某些情况下还能与JVM的生命周期保持一致 (存入老年代)

Java堆区进一步细分可以分为新生代(YoungGen)和老年代(OldGen),新生代可以分为伊甸园区(Eden)、新生区1(from)和新生区2(to)

JDK8及以后

为什么要把Java堆分代?不分代就不能正常工作了么?

经研究,不同对象的生命周期不同。70%-99%的对象都是临时对象,新生代:有Eden、Survivor构成(s0,s1 又称为from to),to总为空,老年代:存放新生代中经历多次依然存活的对象。

其实不分代完全可以,分代的唯一理由就是优化GC性能。 如果没有分代,那所有的对象都在一块,就如同把一个学校的人都关在一个教室。 GC的时候要找到哪些对象没用,这样就会对堆的所有区域进行扫描,而很多对象都是朝生夕死的。 如果分代的话,把新创建的对象放到某一地方,当GC的时候先把这块存储“朝生夕死”对象的区域进行回收,这样就会腾出很大的空间出来。

永久代为什么要被元空间替换?

由于类的元数据分配在本地内存中,元空间的最大可分配空间就是系统可用内存空间。

这项改动是很有必要的,原因有:

(1)为永久代设置空间大小是很难确定的。

在某些场景下,如果动态加载类过多,容易产生Perm区的O0M,比如某个实际Web工程中,因为功能点比较多,在运行过程中,要不断动态加载很多类,经常出现致命错误。 “Exception in thread’ dubbo client x.x connector’java.lang.OutOfMemoryError: PermGenspace”而元空间和永久代之间最大的区别在于:元空间并不在虚拟机中,而是使用本地内存。因此,默认情况下,元空间的大小仅受本地内存限制。

(2)对永久代进行调优是很困难的

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/347126.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

BC C language

题目汇总 No.1 打印有规律的字符(牛牛的字符菱形) 代码展示 #include<stdio.h> int main() {char ch0;scanf("%c",&ch);for(int i0;i<5;i){for(int j0;j<5;j){if((i0||i4)&&j2)printf("%c", ch);else if ((i 1||i3) &&…

发电机纵联差动保护的Simulink仿真

A相电压EA其电压有效值为6060V(对应额定电压为10.5kV的发电机)&#xff0c;相位设置为0。&#xff0c;EB的相位设置为-120。、EC的相位设置为120。&#xff0c;其他设置与EA相同。在图1中,是把A相和C相的电动势分成了两部分ɑ0.9,以仿真发电机内部A、C相故障的情况。 图1 发电机…

任务倒计时App

设计背景 在某一阶段可能需要给自己设置长期任务&#xff0c;比如找工作、考研等&#xff0c;需要一个单纯的任务计时工具&#xff0c;设置完任务的目标时间后&#xff0c;每次打开App时都能直接看到最新的剩余时间 设计步骤 1. 写java源码 由于需要界面显示&#xff0c;需…

R语言 | 使用最简单方法添加显著性ggpubr包

本期教程原文&#xff1a;使用最简单方法添加显著性ggsignif包 本期教程 获得本期教程代码和数据&#xff0c;在后台回复关键词&#xff1a;20240605 小杜的生信笔记&#xff0c;自2021年11月开始做的知识分享&#xff0c;主要内容是R语言绘图教程、转录组上游分析、转录组下游…

五年React手,竟被一个用Ruoyi的Java佬给秒了,这不完了么

被秒了 一个Java摸鱼手&#xff0c;随便用用若依就搞出来一个交互良好&#xff0c;功能强大的管理后台&#xff0c;这让我这个一直用React写管理后台的前端工&#xff0c;很尴尬啊&#xff0c;一下就变小丑了&#xff0c;不行我得抗一波线&#xff0c;用React好好写一个既能对…

如何愉快地实施数仓模型,对比下厨做饭

一般我们建设数仓&#xff0c;有一个链路&#xff1a; 比如这样的 数据从原始层到DWD、DWS层、然后ADS层。 嘿&#xff0c;未来的大数据专家们&#xff01;当我们开始实施数据模型时&#xff0c;不妨参考《大数据之路》这本宝藏书。 让我们一起简化流程&#xff0c;注重细节…

万界星空科技定制化MES系统,实现数字化生产

一、MES生产管理系统强调三个方面&#xff1a; 1、MES是对整个车间制造过程的优化&#xff0c;而不是单一的解决某个生产瓶颈。 2、MES必须提供实时收集生产过程中数据的功能&#xff0c;并作出相应的分析和处理。 3、MES需要与计划层和控制层进行信息交互&#xff0c;通过企业…

项目-基于LangChain的ChatPDF系统

问答系统需求文档 一、项目概述 本项目旨在开发一个能够上传 PDF 文件&#xff0c;并基于 PDF 内容进行问答互动的系统。用户可以上传 PDF 文件&#xff0c;系统将解析 PDF 内容&#xff0c;并允许用户通过对话框进行问答互动&#xff0c;获取有关 PDF 文件内容的信息。 二、…

Linux - 深入理解/proc虚拟文件系统:从基础到高级

文章目录 Linux /proc虚拟文件系统/proc/self使用 /proc/self 的优势/proc/self 的使用案例案例1&#xff1a;获取当前进程的状态信息案例2&#xff1a;获取当前进程的命令行参数案例3&#xff1a;获取当前进程的内存映射案例4&#xff1a;获取当前进程的文件描述符 /proc中进程…

【Linux】信号(二)

上一章节我们进行了信号产生的讲解。 本节将围绕信号保存展开。 目录 信号保存&#xff1a;信号的一些概念&#xff1a;关于信号保存的接口&#xff1a;sigset_t的解释&#xff1a;对应的操作接口&#xff1a;sigprocmask&#xff1a;sigpending&#xff1a;代码实践&#xf…

怎么将3d的模型同比例缩放?---模大狮模型网

在展览3d模型设计过程中&#xff0c;经常需要对3d模型进行缩放以满足不同的需求。然而&#xff0c;有时候缩放操作可能会导致模型失去比例&#xff0c;造成不必要的麻烦。模大狮将介绍如何将展览3D模型按比例缩放&#xff0c;帮助展览设计师们更好地掌握这一关键的模型设计技巧…

我要成为算法高手-双指针篇

目录 什么是双指针?问题1&#xff1a;移动零问题2&#xff1a;复写零问题3&#xff1a;快乐数问题4&#xff1a;盛最多水的容器问题5&#xff1a;有效三角形个数问题6&#xff1a;查找总价格和为目标值的两个商品(两数之和)问题7&#xff1a;三数之和问题8&#xff1a;四数之和…

德克萨斯大学奥斯汀分校自然语言处理硕士课程汉化版(第六周) - 预训练模型

预训练模型 1. 预训练模型介绍 1.1. ELMo1.2. GPT1.3. BERT 2. Seq2Seq 2.1. T52.2. BART 3. Tokenization 1. 预训练模型介绍 在预训练语言模型出现之前&#xff0c;统计语言模型&#xff08;如N-gram模型&#xff09;是主流方法。这些模型利用统计方法来预测文本中的下一个…

Docker系列.Docker Desktop中如何启用Kubernetes

Docker技术概论 Docker Desktop中如何启用Kubernetes - 文章信息 - Author: 李俊才 (jcLee95) Visit me at CSDN: https://jclee95.blog.csdn.netMy WebSite&#xff1a;http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress of this article:https://blog.…

【wiki知识库】06.文档管理接口的实现--SpringBoot后端部分

目录 一、&#x1f525;今日目标 二、&#x1f388;SpringBoot部分类的添加 1.调用MybatisGenerator 2.添加DocSaveParam 3.添加DocQueryVo 三、&#x1f686;后端新增接口 3.1添加DocController 3.1.1 /all/{ebokId} 3.1.2 /doc/save 3.1.3 /doc/delete/{idStr} …

嵌入式系统概述

嵌入式系统是为了特定应用而专门构建的计算机系统&#xff0c;其嵌入式软件的架构设计与嵌入式系统硬件组成紧密相关。 1.嵌入式系统发展历程 嵌入式系统的发展大致经历了五个阶段&#xff1a; 第一阶段&#xff1a;单片微型计算机&#xff08;SCM&#xff09;&#xff0c;及…

贷款业务——LPR、APR、IRR

文章目录 LPR&#xff08;Loan Prime Rate&#xff09;贷款市场报价利率APR&#xff08;Annual Percentage Rate&#xff09;年化百分比利率IRR&#xff08;Internal Rate of Return&#xff09;内部收益率 LPR、APR 和 IRR 是三个不同的金融术语&#xff0c;LPR 是一种市场利率…

干货分享!2024年Instagram营销必备插件

Instagram是营销人员常用的社交媒体平台&#xff0c;通过提升品牌知名度来推动业务增长。今天给大家分享一些超实用的Instagram营销插件&#xff0c;无论是下载图片视频&#xff0c;还是预先发布帖子&#xff0c;这些工具都可以是你的得力助手&#xff0c;让你的INS运营效率蹭蹭…

Unity2D游戏制作入门 | 12(之人物受伤和死亡的逻辑动画)

上期链接&#xff1a;Unity2D游戏制作入门 | 11(之人物属性及伤害计算)-CSDN博客 上期我们聊到了人物的自身属性和受伤时的计算&#xff0c;我们先给人物和野猪挂上属性和攻击属性的代码&#xff0c;然后通过触发器触发受伤的事件。物体&#xff08;人物也好敌人也行&#xff…

如何使用免费的 Instant Data Scraper快速抓取网页数据

Instant Data Scraper 是一款非常简单易用的网页数据爬虫工具&#xff0c;你不需要任何代码知识&#xff0c;只需要点几下鼠标&#xff0c;就可以把你想要的数据下载到表格里面。以下是详细的使用步骤&#xff1a; 第一步&#xff1a;安装 Instant Data Scraper 打开谷歌浏览…