当前位置: 首页 > news >正文

JVM内存管理

一.java程序运行过程

JDK,JRE,JVM 

JVM把我们的字节码翻译成机械能执行的机械码。

JRE除了包含JVM之外,还包含很多java的原生依赖库。

JDK除了包含JRE之外,还包含很多工具,比如javac工具。

.java文件是怎么被执行的

我们的.java文件会被jdk里面的javac工具编译成.class文件,最后在JVM中通过类加载器加载,交给执行引擎来执行,执行有两种方式,一种是通过字节码解释器解释执行,一种事通过JIT编译器执行。

解释执行:JVM是C++语言写的,我们在java语言中new出一个对象,JVM的字节码解释器会帮我我们自动解释成C++,最后new出一个对象。

 解释执行缺点:经过JVM的翻译,速度慢一点。

如果一个方法,一段代码循环次数达到一定次数后,会通过JIT执行(hotsport)。

JIT就是直接把java代码翻译成汇编码(放在JVM的codecache里面),不需要经过解释器处理,好处是比较快,坏处是要对代码进行提前翻译,编译速度会比较长。

JVM的跨平台性:我们写一个类可以在不同的平台运行(windows,linux,android)。并不是说所有平台安装的是一个JVM,官网上对不用操作系统做了不同的JVM包适配。

JVM的语言无关性:与上层使用什么语言无关,只要最后生成的.class文件符合JVM的语法规范就行。

二.运行时数据区域

Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域。

运行时数据区:JVM把它管理的内存区域虚拟化后就是运行时数据区。

直接内存(堆外内存):假如手机内存是8G,JVM虚拟化后的运行时数据区是5G,还有3G内存是JVM没有虚拟化的,但是在Java里面可以通过某个方法区申请这块内存,使用后需要释放。这块内存就叫直接内存,也叫堆外内存。

运行时数据区按类型区分可以分为线程私有区域和线程共享区域。

线程共享区

方法区和堆

方法区存储信息主要:类型信息,域(Field)信息,方法(Method)信息,常量,静态变量,即时编译器编译后的代码缓存(JIT的缓存)。

在java加载类的时候,第一步就是:Java 虚拟机会根据类的全限定名(Package + Class Name)加载 .class 文件,生成对应的二进制字节码,并将其存储在方法区中。在加载阶段之前,Java 虚拟机会先检查该类是否已经被加载过,如果已经被加载过,则不会再加载该类。

public class ObjectAndClass {//静态变量,存储在方法区里面static int age = 18;//常量,存储在方法区里面final static int sex = 1;//成员变量,是一个对象,存储到堆里面,但是person引用存储在栈里面,Person类型存储在方法区里面Person person = new Person();//成员变量,基础数据类型,分配在堆里面private boolean isRight;/*** 引用类型总是被分配到“堆”上。不论是成员变量还是局部* 基础类型总是分配到它声明的地方:成员变量在堆内存里,局部变量在栈内存里。* @param args*/public static void main(String[] args) {//局部变量,但是是个对象,存储在堆上,但是person引用存储在栈里面,Person类型存储在方法区里面Person person1 = new Person();//局部变量int x = 8;//局部变量String a = "aaa";//局部变量(对象)ObjectAndClass objectAndClass = new ObjectAndClass();objectAndClass.isRight = true;}static class Person {private int age;public int getAge() {return age;}public void setAge(int age) {this.age = age;}}
}

  * 引用类型总是被分配到“堆”上。不论是成员变量还是局部
  * 基础类型总是分配到它声明的地方:成员变量在堆内存里,局部变量在栈内存里。 

方法区具体存储什么可参考:Java虚拟机(JVM)的方法区(Method Area)存储了什么内容?_jvm方法区存放什么-CSDN博客

java类的加载顺序:

Java 类的加载顺序 - 我爱学习网 (5axxw.com)

线程私有

虚拟机栈

每次启动一个线程,就会为当前线程创建一个虚拟机栈。

虚拟机栈:存储当前线程运行java方法所需的数据,指令,返回地址。

大小限制:-Xss

public class MethodAndStack {public static void main(String[] args) {A();}public static void A(){B();}public static void B(){C();}public static void C(){}
}

现在我们看到上诉代码,当我们启动这个程序,会为当前的线程创建一个虚拟机栈。这个虚拟机栈中存储当前线程运行java方法所需的数据,指令,返回地址。

当我们执行到main方法的时候,会往当前虚拟机栈中压入一个栈帧。

当我们执行main的时候,会跳入A方法,又往虚拟机栈里面压入A方法的栈帧。A方法有调B方法,又会往虚拟机栈里面压入B方法的栈帧。B方法最后调用C方法,会往虚拟机栈里面压入C方法的栈帧。

如果C方法执行完毕,C方法的栈帧从虚拟机栈里面退出;B方法,A方法,main方法执行完后,对应的栈帧都要从虚拟机栈里面退出。

栈溢出:如果我在A方法里面调用A方法,形成死递归的话,就会一直往虚拟机栈里面压入A方法的栈帧。栈帧会有一定的大小,当数量足够多的时候,虚拟机栈的内存就会不够,造成栈溢出。(方法调用层次太深也有可能)

栈帧

虚拟机栈:存储当前线程运行java方法所需的数据,指令,返回地址。

程序计数器:指向当前线程正在执行的字节码的地址。

栈帧:包括局部变量表,操作数栈,动态连接,完成出口。

我们先写一个Person类:

public class Person {public int work()throws Exception{int x =1;int y =2;int z =(x+y)*10;return z;}public static void main(String[] args) throws Exception{Person person = new Person();person.work();//方法属于本地方法 ---本地方法龙person.hashCode();}
}

我们知道当执行到work方法的时候,会往当前线程的虚拟机栈压入一个栈帧,我们来看一下work方法执行的过程,栈帧里面都干了什么。

我们知道JVM执行的是.class文件,所以我们先找到.class文件。

 我们cmd到这个文件夹目录下,然后执行javap -v Person.class,生成的就是字节码:

 

 里面的Constant pool是静态常量池。

可以看到为我们自动生成了一个Person的构造方法,除此之外还有一个work方法,一个main方法。(就算我们自己不定义类的构造方法,字节码里面也会自动帮我们生成一个)

我们这边重点来看work方法里面的代码:

这些代码是什么意思呢?执行这些方法的时候,栈帧又会怎么变化?

我们看到最前面有0,1,2,3等等,这些是字节码的地址,给程序计数器使用的。0后面的iconst_1表示需要内存new出一个int的常量并且把它压入操作数栈。

当执行到1:istore_1的时候,程序计数器里面的count变成1,istore_1表示把操作数栈栈顶的数据放倒局部变量表下标为1的地方。istore_1最后面的表示的是局部变量表的位置。

 让我们回到我们的java代码里面,我们int x =1;这一行代码,在字节码里面变成了 :

          0: iconst_1

          1: istore_1

我们的x的值被存到局部变量表中了。

那我们就可以推导得到 

           2: iconst_2
           3: istore_2

这两行字节码,首先程序计数器的count变成2,然后在操作数栈里面压入一个2的常量,然后程序计数器的count变成3,最后把操作数栈栈顶的2移出到局部变量表下标为2的位置。

接下来我们java代码执行int z =(x+y)*10,我们的x和y已经定义出来了;查看字节码发现

        4:iload_1

        5:iload_2

这两行字节码的意思是把局部变量下标为1,局部变量下标为2的数据压入操作数栈中。

       6:iadd表示从操作数栈里面取两个数,出栈相加,把结果入栈。

7:bipush         10   这行字节码表示往操作数栈里面推入一个10,因为iconst命令只能压入-1到5的数字,大于5就压不动了,需要使用bipush来推入操作数栈。

接下来执行9:imul,我们可以推理出这个是把操作数栈里面的两个数字先取出来,然后做乘法,最后把得到的值重新压入操作数栈。

10:istore_3就是把位于操作数栈栈顶的30,移动到局部变量表下标为3的地方。这里也就是给z赋值。

因为我们定义的方法是有返回值的,所以接下来执行11:iload_3把局部变量表下标为3的数字压入操作数栈。

最后执行12:ireturn,带着操作数栈里面的30返回到main方法里面继续执行。

以上就是work方法在执行过程中栈帧的变化,但是为什么0到12中间少了一个8呢?

我们在cmd里面得到的是字节码的指令,0到12是针对work方法字节码的偏移量,有的指令比较大就会大于1行。所以我们程序计数器记录的是当前方法的偏移量。

完成出口:我们执行main方法的时候,拿到字节码也会看到和work方法一样的0...12,这表示的是字节码的行号(针对本方法的偏移量)。我们从main方法执行person.work()跳到work方法,假如person.work()的行号是3,跳转到work方法,work的栈帧的完成出口就是3。当work方法执行完成后,通过完成出口回到main方法相应的行数继续执行。

动态连接:与多态有关。

注意:程序计算器记录的东西可能会重复,因为我在main方法里面会记录0,1,2,3,4。当跳到work方法的时候也会记录0,1,2,3,4。但是没关系,虚拟机栈同时只会执行一个方法,只会执行一个栈帧。

程序计数器的作用:当CPU切到另外一个线程的时候,当前线程暂停执行,当回到当前线程的时候,可以从程序计数器记录的行号继续执行。

问题:匿名内部类使用局部引用为什么要用final?

相关文章:

JVM内存管理

一.java程序运行过程 JDK,JRE,JVM JVM把我们的字节码翻译成机械能执行的机械码。 JRE除了包含JVM之外,还包含很多java的原生依赖库。 JDK除了包含JRE之外,还包含很多工具,比如javac工具。 .java文件是怎么被执行的 我们的.java文件会被…...

将 Python 和 Rust 融合在一起,为 pyQuil® 4.0 带来和谐

文章目录 前言设定方向从 Rust 库构建 Python 软件包改装 pyQuil异步困境回报:功能和性能结论 前言 pyQuil 一直是在 Rigetti 量子处理单元(QPUs)上构建和运行量子程序的基石,通过我们的 Quantum Cloud Services(QCS™…...

Spring Boot应用程序中VO的理解及使用

在Spring Boot应用程序中,VO(View Object)通常用于表示视图层所需的数据,这些数据来自于业务逻辑层或数据访问层。VO的主要目的是将业务逻辑层的数据结构转换为视图层可以使用的数据结构,使得视图层可以直接使用VO中的…...

华为交换机ETH-TRUNK链路聚合lacp模式与手工模式

SW1配置如下 vlan batch 10interface Eth-Trunk1port link-type trunkport trunk allow-pass vlan 10mode lacp-static #手工模式删除改行max active-linknumber 2 #手工模式删除改行trunkport GigabitEthernet 0/0/1 to 0/0/2#配置为主设备(修改优先级&…...

函数图像化

函数图像化 在进行模型提取时,往往会需要选择拟合的函数,因此,了解函数的图像对于模型拟合提取有益,以下是常见的一些函数的曲线 1 二次函数 常见的耳二次函数曲线,转换x与y数量级差异仅一个数量级, 2 三…...

gnu工程的编译 - 以libiconv为例

文章目录 gnu工程的编译 - 以libiconv为例概述gnu官方源码包的发布版从官方的代码库直接迁出的git版源码如果安装了360, 需要添加开发相关的目录到信任区生成 configrue 的方法备注END gnu工程的编译 - 以libiconv为例 概述 gnu工程的下载分2种: gnu官方源码包的发布版 这种…...

在 CentOS 7.8 上安装 Node.js

1.安装 NVM(Node Version Manager): curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash这将从 NVM 的 GitHub 仓库下载安装脚本并执行。请注意,您需要重新启动终端或者执行 source ~/.bashrc 以…...

【数据分析实战】冰雪大世界携程景区评价信息情感分析采集词云

文章目录 引言数据采集数据集展示数据预处理 数据分析评价总体情况分析本人浅薄分析 各游客人群占比分析本人浅薄分析 各评分雷达图本人浅薄分析 差评词云-可视化本人浅薄分析 好评词云-可视化本人浅薄分析 综合分析写在最后 今年冬天,哈尔滨冰雪旅游"杀疯了&q…...

BIND-DNS配置介绍

一、主要配置文件 /etc/named.conf options { //Option 段全部配置 listen-on port 53 { 127.0.0.1; };//表示BIND将在53端口监听,若需要对所有IP进行监听,则修改为// listen-on port 53 { any; }; directory "/var/named"…...

Python技巧

Python,现如今非常热门的一种编程语言,在人工智能中大放异彩。做任何事都需要技巧,这可以大大提高效率,学习Python,同样如此! 第一个就是assret语句,让我们看下面一个关于折扣的例子: def dic…...

几种常见的CSS三栏布局?介绍下粘性布局(sticky)?自适应布局?左边宽度固定,右边自适应?两种以上方式实现已知或者未知宽度的垂直水平居中?

几种常见的CSS三栏布局 流体布局 效果&#xff1a; 参考代码&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1…...

箭头函数 - JavaScript的新宠儿

&#x1f4e2; 鸿蒙专栏&#xff1a;想学鸿蒙的&#xff0c;冲 &#x1f4e2; C语言专栏&#xff1a;想学C语言的&#xff0c;冲 &#x1f4e2; VUE专栏&#xff1a;想学VUE的&#xff0c;冲这里 &#x1f4e2; CSS专栏&#xff1a;想学CSS的&#xff0c;冲这里 &#x1f4…...

操作系统期末复习知识点

目录 一.概论 1.操作系统的介绍 2.特性 3.主要功能 4.作用 二.进程的描述与控制 1.进程的定义 2.特性 3.进程的创建步骤 4.基本状态转化 5.PCB的作用 6.进程与线程的比较 三.进程同步 1.同步的概念&#xff08;挺重要的&#xff09; 2.临界区 3.管程和进程的区…...

[英语学习][23][Word Power Made Easy]的精读与翻译优化

[序言] 译者的这次翻译, 完全直译, 生硬无比. [英文学习的目标] 提升自身的英语水平, 对日后编程技能的提升有很大帮助. 希望大家这次能学到东西, 同时加入我的社区讨论与交流英语相关的内容. [原著英文与翻译版对照][第22页] Knowledge is chiefly in the form of words…...

吉林大学19、21级计算机学院《计算机网络》期末真题试题

一、21级&#xff08;考后回忆&#xff09; 一、不定项选择&#xff08;一共10个选择题&#xff0c;一个两分&#xff0c;选全得满分&#xff09; 不定项&#xff1a;可以选择1~4个 考点有&#xff1a; ①协议、服务 ②码分多路复用通过接受码片序列&#xff0c;求哪个站点发送…...

python练习3【题解///考点列出///错题改正】

一、单选题 1.【单选题】 ——可迭代对象 下列哪个选项是可迭代对象&#xff08; D&#xff09;&#xff1f; A.(1,2,3,4,5) B.[2,3,4,5,6] C.{a:3,b:5} D.以上全部 知识点补充——【可迭代对象】 可迭代对象&#xff08;iterable&#xff09;是指可以通过迭代&#xff…...

LINUX服务器防火墙nf_conntrack问题一例

一、故障现象 业务反馈服务异常,无法响应请求&#xff0c;从系统日志 dmesg 或 /var/log/messages 看到大量以下记录&#xff1a;kernel: nf_conntrack: table full, dropping packet. 二、问题分析 业务高峰期服务器访问量大&#xff0c;内核 netfilter 模块 conntrack 相关参…...

经典八股文之RocketMQ

核心概念 NameServer nameserver是整个rocketmq的大脑&#xff0c;是rocketmq的注册中心。broker在启动时向所有nameserver注册。生产者在发送消息之前先从 NameServer 获取 Broker 服务器地址列表(消费者一 样)&#xff0c;然后根据负载均衡算法从列表中选择一台服务器进行消…...

Pandas之从sql库中导入数据的几种方法分析

1.使用mysql-connector-python库将SQL文件导入到Python中&#xff0c;并查询数据库中的表 确保已经安装mysql-connector-python库 #导入模块 import mysql.connector# 建立与MySQL数据库的连接 conn mysql.connector.connect(host"localhost",user"username&…...

18. Mysql 存储过程,实现动态数据透视

文章目录 概述常见操作创建存储过程存储过程局部变量定义和赋值查看存储过程删除存储过程调用存储过程 示例-动态数据透视详细讲解总结参考资料 概述 Mysql 存储过程是一组预先编译的 sql 语句集合&#xff0c;它们被存储在数据库中&#xff0c;并可以被多次调用执行。存储过程…...

VuePress部署到GitHub Pages

一、git push自动部署 1、创建用于工作流的文件 在项目根目录下创建一个用于 GitHub Actions 的工作流 .yml 文件 name: docson:# 每当 push 到 main 分支时触发部署push:branches: [main]# 手动触发部署workflow_dispatch:jobs:docs:runs-on: ubuntu-lateststeps:- uses: a…...

git 本地仓库

本地仓库 start.bat 启动...

Hive实战:分科汇总求月考平均分

文章目录 一、实战概述二、提出任务三、完成任务&#xff08;一&#xff09;准备数据1、在虚拟机上创建文本文件2、上传文件到HDFS指定目录 &#xff08;二&#xff09;实现步骤1、启动Hive Metastore服务2、启动Hive客户端3、创建分区的学生成绩表4、按分区加载数据5、查看分区…...

快速搭建知识付费小程序,3分钟即可开启知识变现之旅

明理信息科技知识付费saas租户平台 在当今数字化时代&#xff0c;知识付费已经成为一种趋势&#xff0c;越来越多的人愿意为有价值的知识付费。然而&#xff0c;公共知识付费平台虽然内容丰富&#xff0c;但难以满足个人或企业个性化的需求和品牌打造。同时&#xff0c;开发和…...

【计算机图形学划重点】第一讲-Pipeline and Introduction

基础知识 Vertex&#xff08;顶点&#xff09; define the location of primitives in space, and consists of vertex stream. 顶点用于定义空间中基本图形&#xff08;primitives&#xff09;的位置。它包含了一个顶点流&#xff08;vertex stream&#xff09;&#xff0c…...

面试题-DAG 有向无环图

有向无环图用于解决前后依赖问题&#xff0c;在Apollo中用于各个组件的依赖管理。 在算法面试中&#xff0c;有很多相关题目 比如排课问题&#xff0c;有先修课比如启动问题&#xff0c;需要先启动1&#xff0c;才能启动2 概念 顶点&#xff1a; 图中的一个点&#xff0c;比…...

vite + vue3引入ant design vue 报错

npm install ant-design-vue --save下载插件并在main.ts 全局引入 报错 解决办法一&#xff1a; main.ts注释掉全局引入 模块按需引入 解决办法二 将package.json中的ant-design-vue的版本^4.0.0-rc.4改为 ^3.2.15版本 同时将将package-lock.json中的ant-design-vue的版本…...

使用EasyPoi导入数据并返回失败xls

添加依赖 <!-- https://mvnrepository.com/artifact/cn.afterturn/easypoi-base --> <dependency><groupId>cn.afterturn</groupId><artifactId>easypoi-base</artifactId><version>4.4.0</version> </dependency> 工…...

机械配件移动商城课程概述

项目介绍 开发准备 任务 开源库介绍 框架搭建 工具类...

prometheus-docker 快速安装

镜像加速 sudo mkdir -p /etc/docker sudo tee /ect/docker/daemon.json << "EOF" {"register-mirros": ["http://hub-mirror.c.163.com"] } EOF安装docker export DOWNLOAD_URL"http://mirrors.163.com/docker-ce" curl -fsSl…...

dw怎么做别人可以看的网站/黄页网推广服务

Mysql-5.7.20 升级 mysql-8.0.14-1 操作前建议先查阅以下网页初步了解Mysql版本升级信息 https://blog.csdn.net/u012946310/article/details/81880050 一、查看环境信息 cat /etc/redhat-release mysql -V 二、备份数据库 &#xff08;-A 参数是备份全部数据库的数据和结构&…...

怎么查寻一个网站做的竞价/国内新闻大事20条

ssh key有问题&#xff0c;连接不上服务器 git clone的时候遇到的这个问题&#xff0c;原来是我本地没有设置好ssh 1、首先我得重新在git设置一下身份的名字和邮箱 git config --global user.name “yourname” git config --global user.email“youremail.com" 注&am…...

商城做网站哪家好/词语搜索排行

主要内容: 1. 函数名的使用以及第⼀类对象2. 闭包3. 迭代器1. 函数名的使用以及第⼀类对象 函数名是一个变量, 但它是一个特殊的变量, 与括号配合可以执行函数的变量。 (1) 函数名的内存地址 def func():print("呵呵") print(func) #<function func at…...

福田欧曼价格/网站推广优化招聘

Topshelf是一个开源的跨平台的宿主服务框架&#xff0c;只需要几行代码就可以构建一个很方便使用的windows服务。 首先安装nuget包 Topshelf。 创建一个.net core控制台程序 1 static void Main(string[] args)2 {3 #region 容器注入4 var services …...

建设网站要学什么/seo投放

hive的tar包下载地址&#xff1a;链接&#xff1a;https://pan.baidu.com/s/1m3VKT2-kIgR1QyjmfnWvGw?pwdr45r 提取码&#xff1a;r45rmysql的tar包&#xff1a;链接&#xff1a;https://pan.baidu.com/s/1--s1m3hfNNKEVGkFEqi5iA?pwdb7h4 提取码&#xff1a;b7h4由于hive的元…...

苏州快速建设网站公司/免费好用的网站

建立Empty Application&#xff0c;新建Storyboard并添加View Controller 控件后运行为空白&#xff0c;并报错 控制台显示&#xff1a; 2012-07-18 15:21:57.338 apress-8[664:f803] Application windows are expected to have a root view controller at the end of applicat…...