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) {
    //递归调用main
    main(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.mfbz.cn/a/699710.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

63-目录操作(QDir类)及展示系统文件实战

一、目录操作(QDir 类) #include <QCoreApplication>#include <QDir> #include <QStringList> #include <QtDebug>// 自定义函数实现获取目录下大小qint64 GetDirFileInfoSizeFunc(const QString &qpath) {// QDir类专门用来操作路径名称或底层文…

catia零件装配时预览零件的形状

这样的显示方式看不到 选择大或中图标就可预览零件形状

Qt | openSSL将TCP数据进行不对称(RSA)加密传输-windows平台实操(可行)

01、windows平台工具准备 QtQt5.14.2openSSL下载(选择适合自己的版本即可)https://slproweb.com/products/Win32OpenSSL.htmlTCP调试助手调试助手02、简介 首先简单介绍一下openssl。接着描述如何在windo

新增多种图表类型,新增视频、流媒体、跑马灯组件,DataEase开源数据可视化分析工具v2.7.0发布

2024年6月11日&#xff0c;人人可用的开源数据可视化分析工具DataEase正式发布v2.7.0版本。 这一版本的功能变动包括&#xff1a;图表方面&#xff0c;新增对称条形图、桑基图、流向地图、进度条等图表类型&#xff0c;并对已有的仪表盘、指标卡、明细表、汇总表、水波图、象限…

(十二)人工智能应用--深度学习原理与实战--模型编译及训练参数的选择

神经网络模型的编译实际上是为网络指定几个非常重要的运行参数,包括优化器、损失函数(误差函数】和评价指标,这三者也代表着神经网络的核心运行机制----通过损失函数来计算网络误差、通过优化器来调整网络参数以降低误差、通过评价指标来衡量网络的性能。神经网络训练时除了…

香港裸机云多IP服务器与普通独享IP服务器的区别

在当前的云计算和服务器托管领域&#xff0c;香港裸机云多IP服务器和普通独享IP服务器是两种常见的选择。它们各自具有独特的特点和优势&#xff0c;适用于不同的应用场景。以下是对这两种服务器类型的详细比较&#xff1a; 一、概念定义 香港裸机云多IP服务器&#xff1a;这是…

【因果推断python】28_面板数据和固定效应2

目录 固定效应 固定效应 为了方面后面更正式地讲述&#xff0c;让我们首先看一下我们拥有的数据。按照我们的例子&#xff0c;我们将尝试估计婚姻对收入的影响。我们的数据包含多年以来多个个体 (nr) 的这两个变量&#xff0c;married 和lwage。请注意&#xff0c;工资采用对数…

【iOS】—— 响应者链和事件传递链

【iOS】—— 响应者链和事件传递链 响应者连和事件传递链概念响应者响应链事件响应者响应链事件iOS中的事件类型&#xff1a;UIKit继承图UIRseponderUITouchUIEvent 事件的产生与传递传递链传递过程 总结 响应者连和事件传递链 概念 响应者 由离用户最近的view向系统传递。i…

【CGAL】Region_Growing检测圆柱,保存结果并输出圆柱体参数

目录 说明代码展示结果展示问题说明 说明 这篇博客以代码为主&#xff0c;使用CGAL中的region growing方法检测圆柱体。将不同的圆柱按不同颜色保存&#xff0c;并输出圆柱体的中心坐标、轴方向以及半径。 region growing的具体思想网上的文章已经有很多&#xff0c;可以参考这…

安装mysql5.7,然后安装mysql workbench进行管理。

1、下载mysql5.7 MySQL :: Download MySQL Installer 这个是32位的安装版 MySQL :: Download MySQL Community Server (Archived Versions) 这个是zip版 这里我下载的是zip版本。 下载完成后&#xff0c;解压缩&#xff0c;然后新建文件my.ini进行配制。 my.ini [mysqld]…

Django DetailView视图

Django的DetailView是一个用于显示单个对象详情的视图。下面是一个使用DetailView来显示单个书籍详情的例子。 1&#xff0c;添加视图 Test/app3/views.py from django.shortcuts import render# Create your views here. from django.views.generic import ListView from .m…

数据结构预备知识(Java):包装类泛型

1、包装类 1.1 包装类 在Java中&#xff0c;每一个基本数据类型都有一个对应的包装类&#xff1a; 在SE的学习中我们已有过简单了解。 我们可以注意到&#xff0c;除了int类型的包装类为Integer&#xff0c;char类型的包装类为Character外&#xff0c;其余基本类型的包装类均…

wordpress主题开发

科普一&#xff1a;wordpress 是一套用 php 这个语言写的CMS后台管理系统&#xff0c;即我们大家的 wordpress 网站后台是一样的&#xff0c;能体现我们网站外观不同的地方就在于wordpress主题&#xff08;即皮肤&#xff09;&#xff0c;而这个主题的基本构成是 htmlcssjavasc…

JMH309【亲测】典藏3D魔幻端游【剑踪3DⅢ】GM工具+开区合区工具+PC客户端+配置修改教程+Win一键服务端+详细外网视频教程

资源介绍&#xff1a; 经典不错的一款端游 GM工具开区合区工具PC客户端配置修改教程Win一键服务端详细外网视频教程 资源截图&#xff1a; 下载地址

任务倒计时App

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

使用MySQL

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 1 下载安装MySQL MySQL是一款开源的数据库软件&#xff0c;由于其免费特性得到了全世界用户的喜爱&#xff0c;是目前使用人数最多的数据库。下面将…

Unity【入门】重要组件和API

Unity重要组件和API 文章目录 1、最小单位GameObject1、成员变量2、静态方法1、代码创建Unity自带几何体 CreatePrimitive2、查找对象3、实例化对象&#xff08;克隆对象&#xff09;的方法4、删除对象的方法5、切换场景不移除 3、成员方法1、创建空物体2、为对象动态添加脚本(…

基数排序详解

目录 一、桶排序思想 1.1 什么是桶排序 1.2 桶排序的步骤 二、基数排序思想 2.1 什么是基数排序 2.2 实现方式 2.3 图解 三、代码思路 3.1 前置工作 3.2 映射 3.3 排序 四、C语言源码 一、桶排序思想 1.1 什么是桶排序 桶排序(Bucket sort)是一种排序算法&#xff…

网络安全课程开发

我们为卡巴斯基实验室开发了一个交钥匙教育门户网站&#xff0c;并为其开设了网络安全课程。在资源上&#xff0c;你可以熟悉课程的理论部分-观看视频或阅读插图文本版本&#xff0c;然后通过回答问题来验证你的知识。通过最终测试后&#xff0c;用户将获得证书。 对于这个项目…

Pythone 程序打包成 exe

1.安装pyinstaller # 安装 pip install pyinstaller # 查看版本 pyinstaller -v2.更新pyinstaller 版本 # 更新 pip install --upgrade pyinstaller # 查看版本 pyinstaller -v3.切换到 py文件所在目录 #切换到.py所在的目录 E: cd cd E:\x-svn_x-local\04PythoneProjects\A…