(JVM)深入JAVA底层 JVM(Java 虚拟机)!带你认识JVM、程序计数器、JVM栈和方法栈还有堆内存!看看JAVA针对这些内存空间都做了什么吧!

1. 什么是JVM

java 二进制字节码的运行环境,简称:java 虚拟机(Java Virtual Machine)

2. 好处是什么

  • 一次编写,到处运行
  • 自动内存管理,GC垃圾回收功能
  • 数组下标越界检查
  • 多态

3. jdk、jre、jvm

在这里插入图片描述

4. 学习JVM有什么用?

  1. 面试
  2. 理解底层实现原理
  3. 中高级程序员的必备技能

5. 常见的JVM

JVM是一个规范,只要你遵守规范,那么也可以自己写一个JVM出来

现在最出名的就是Oracle的JVM,以前就是 Eclipse J9

在这里插入图片描述
在这里插入图片描述

6. PC Register(程序计数器)

在这里插入图片描述

右侧为 JAVA 底层源码。是最基础的打印效果

左侧为 编译后的 二进制字节码,

  • 左侧绿色数字代表在内存中的内存地址,

  • 右侧黑色数字,代表 一行源码 在字节码中所占的标符

6.1 流程:

  1. 解释器 通过 PC Register 获得字节码 一行源码 的内存地址(通过寄存器)
  2. 解释器将对应内存地址中的字节码进行转换为机器码
  3. 转为 机器码 后交给CPU处理

6.2 作用:

PC Register 的作用:记住下一条JVM指令的执行地址(内存地址)

6.3 特点

  1. 线程是私有的

    其每一次转换线程完成执行地址交换,都会记录在独自的线程中,若是换线程执行结束后,执行地址记录将会混乱

  2. 不会存在内存溢出

7. JVM Stacks(虚拟机栈)

栈:线程运行的内存空间

栈帧:内存空间中的数据(每个方法所运行时需要的内存)

在这里插入图片描述

7.1 定义

  • 每个线程运行时所需要的内存,称为 虚拟机栈

  • 每个栈由多个栈帧(Frame)构成,对应着每次方法调用时所占用的内存

  • 每个线程只能由一个活动栈帧对应着当前正在执行的那个方法
    在这里插入图片描述

当最后一个方法(栈帧)用完后,变为一步步变为最初的方法(栈帧)

在这里插入图片描述

7.2 问题解析

  1. 垃圾回收是否涉及栈内存?

    不会,栈内存就是会在每次栈帧使用完后就会被弹出栈,不用GC的管理,GC管理堆内存

  2. 栈内存分配越大越好吗?

    并不会,内存分配越大,递归调用次数越多罢了,并不会加快程序的运行效率

    -Xss size(线程栈内存参数)

    linux、macOS、Orade Solaris(64-bit):1024KB

    windows:根据虚拟内存自动分配

  3. 方法内的局部变量是否线程安全?

    常态来说,不会。

    若方法交由两个线程执行,那么 一个动态变量 就会存在于这两个线程中执行,结果不影响

    在这里插入图片描述

    但若是静态变量(static),它会将运行交由两个线程,其线程完成计算结果后再交给静态变量更新数值,故而有可能会影响结果静态变量的线程安全

    在这里插入图片描述

    如果方法内的局部变量没有逃离方法的作用范围,它是线程安全的

    如果是局部变量引用了对象,并逃离方法的作用方法,需要考虑线程安全

 /*
            线程安全问题
         */
StringBuilder sb = new StringBuilder();
sb.append(3);
sb.append(4);
sb.append(5);
new Thread(()->{
    m2(sb);
}).start();


/**
     * 线程安全
     */
public static void m1(){
    StringBuilder sb = new StringBuilder();
    sb.append(1);
    sb.append(2);
    System.out.println(sb.toString());
}
/**
     * 线程不安全
     * @param sb
     */
public static void m2(StringBuilder sb){
    sb.append(1);
    sb.append(2);
    System.out.println(sb.toString());
}

/**
     * 线程不安全
     * @return
     */
public static StringBuilder m3(){
    StringBuilder sb = new StringBuilder();
    sb.append(1);
    sb.append(2);
    return sb;
}

7.3 栈内存溢出

7.3.1 导致栈内存溢出的原因

  1. 栈帧过多导致栈内存溢出 (递归)
    在这里插入图片描述

  2. 栈帧过大导致栈内存溢出
    在这里插入图片描述

7.4 线程运行诊断

7.4.1 cpu占用过多(linux环境)

  1. 用 top 指令 定位哪个进程对 CPU 占用过高

  2. ps H -eo pid,tid,%cpu | grep 进程id

    (通过ps命令进一步定位是哪个线程引起的cpu占用过高)

  3. jstack 进程id

    (可以根据线程id找到有问题的线程,进一步定位到问题代码的源码行号)

7.4.2 程序运行时间很长时间没有结果

  1. 死锁问题,同样通过 jstack 进程id,查看源码错误

7.5 代码实现

public class tStack {
    public static void main(String[] args) {
//        Integer integer = demo1(1);
//        System.out.println(integer);

        /*
            线程安全问题
         */
        StringBuilder sb = new StringBuilder();
        sb.append(3);
        sb.append(4);
        sb.append(5);
        new Thread(()->{
            m2(sb);
        }).start();

    }

    public static Integer demo1(int a){
        return demo2(a+2);
    }

    public static Integer demo2(int b){
        return b;
    }

    /**
     * 线程安全
     */
    public static void m1(){
        StringBuilder sb = new StringBuilder();
        sb.append(1);
        sb.append(2);
        System.out.println(sb.toString());
    }

    /**
     * 线程不安全
     * @param sb
     */
    public static void m2(StringBuilder sb){
        sb.append(1);
        sb.append(2);
        System.out.println(sb.toString());
    }

    /**
     * 线程不安全
     * @return
     */
    public static StringBuilder m3(){
        StringBuilder sb = new StringBuilder();
        sb.append(1);
        sb.append(2);
        return sb;
    }


}

8. Native Method Stacks(本地方法栈)

线程私有

它本身的作用就是为本地方法接口提供一个内存空间

8.1 本地方法接口(C/C++ 实现)

对底层CPU进行指令输送,JAVA本身是做不到的,所以得由C/C++实现
它中间会有一个缓存区,也就是直接内存,JAVA通过这个内存区才能够获得到 java对象

9. Heap 堆

线程共享区域

  • 通过new关键字,创建对象都会使用堆内存

特点:

  • 它是线程共享的,所有堆中的对象都需要考虑线程安全问题
  • 垃圾回收机制会干涉,在堆中长时间不使用的数据会被 GC 释放

9.1 堆内存溢出

/**
 * 堆内存溢出:java.lang.OutOfMemory: Java heap space
 */
public class OutOfHeap {

    public static void main(String[] args) {
        int i =0;
        try{
            ArrayList<String> integers = new ArrayList<>();
            String a = "hello";
            while (true){
                integers.add(a);
                a = a+a;
                i++;
            }

        }catch (Exception e){
            e.getStackTrace();
            System.out.println(i);
        }
    }
}

9.2 堆内存诊断

    1. jps 工具(命令行)

jps(Java Virtual Machine Process Status Tool)是JDK提供的一个可以列出正在运行的Java虚拟机的进程信息的命令行工具,它可以显示Java虚拟机进程的执行主类(Main Class,main()函数所在的类)名称、本地虚拟机唯一ID(LVMID,Local Virtual Machine Identifier)等信息。另外,jps命令只能显示它有访问权限的Java进程的信息。

虽然jps命令的功能比较单一,但它使用的频率却很高。对于本地虚拟机来说,本地虚拟机唯一ID和操作系统的进程ID(PID,Process Identifier)是一致的,如果同时启动多个Java虚拟机进程,无法根据进程名称确定某个进程,我们就是使用jps命令显示主类名称的功能区分出来。

jps 虚拟机ID 进程ID
    1. jmap 工具

jmap是jdk中提供的一个用来监视进程运行中的jvm物理内存的占用情况的工具。该进程内存内,所有对象的情况,例如产生了哪些对象,对象数量。当系统崩溃时,jmap 可以从core文件或进程中获得内存的具体匹配情况,包括Heap size, Perm size等。

jmap -heap pid

使用jmap会影响线上运行的应用,所以尽量不要在线上执行此命令。

在java9及以上的版本,无法通过jmap -heap pid命令查看堆内存使用情况了。

在java9以后,引入了全新的命令行工具:jhsdb

jhsdb 包含了很多的模块,对应着各个区块的功能

  • 在java8以后版本的使用
jhsdb jmap --pid 33504 --heap

由于版本更新,JVM指令都整合在了 jhsdb 中

    1. jconsole工具

JConsole 是一种 Java 监控和管理控制台工具,可以用于监视 Java 虚拟机(JVM)的性能和资源利用情况。它提供了一种图形化界面,可以实时查看 JVM 的运行状态、内存使用情况、线程活动、垃圾回收等信息,以及执行一些管理操作。

使用 JConsole 可以帮助开发人员和系统管理员进行性能调优、内存泄漏排查和故障诊断,从而提高应用程序的可靠性和性能。

控制台直接输入命令:jconsole

在这里插入图片描述

    1. JVisualVM工具

JVisualVM是JDK自带的性能检测工具,路径在%JAVA_HOME%/bin下面

可以对堆内存进行dump、快照以及性能可视化分析,也可以安装插件对堆外内存进行分析(我用Buffer Pool),如果项目要求不是特别高,这一款工具已经足够强大加易用。但是也有缺点,据我所知,这些数据是通过RMI协议进行传输,而且监视那一栏采样时间是2S,可能采样精度不够高。

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

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

相关文章

OLAP平台架构演化历程

OLAP平台架构演化历程 0 导读 随着大数据的持续发展及数字化转型的兴起&#xff0c;大数据OLAP分析需求越来越迫切&#xff0c;不论是大型互联网企业&#xff0c;还是中小型传统企业&#xff0c;都在积极探索及实践OLAP引擎选型及平台架构建设&#xff0c;大数据技术的蓬勃发展…

Kaggle入门指南(Kaggle竞赛)

文章目录 Kaggle 入门指南1. Kaggle 的功能概述1.1 竞赛1.2 数据集1.3 学习与教程1.4 社区 2. 注册与设置2.1 创建账户2.2 完善个人资料 3. 探索数据集3.1 查找数据集3.2 下载数据集示例代码&#xff1a;加载数据集 3.3 数据预处理示例代码&#xff1a;数据预处理 4. 参与竞赛4…

docker 可用镜像服务地址(2024.10.31亲测可用)

1.错误 Error response from daemon: Get “https://registry-1.docker.io/v2/” 原因&#xff1a;镜像服务器地址不可用。 2.可用地址 编辑daemon.json&#xff1a; vi /etc/docker/daemon.json内容修改如下&#xff1a; {"registry-mirrors": ["https://…

TortoiseSVN小乌龟下载安装(Windows11)

目录 TortoiseSVN 1.14.7工具下载安装 TortoiseSVN 1.14.7 工具 系统&#xff1a;Windows 11 下载 官网&#xff1a;https://tortoisesvn.subversion.org.cn/downloads.html如图选 TortoiseSVN 1.14.7 - 64 位 下载完成 安装 打开 next&#xff0c;next Browse&#xf…

CAD图纸防泄密|哪些措施可以加密公司图纸?五个宝藏方法分享,2024必读!

在工程设计领域&#xff0c;CAD图纸作为企业的核心资产&#xff0c;其安全性至关重要。一旦图纸泄露&#xff0c;不仅可能给企业带来重大的经济损失&#xff0c;还可能损害企业的声誉和竞争力。 那么&#xff0c;怎么实现CAD图纸防泄密呢&#xff1f; 以下是五个CAD图纸防泄密…

Centos7安装最新版EMQX(v5.8.1)

引言 由于从centos停止维护&#xff0c;导致yum源不可用&#xff0c;好多方法安装都有问题&#xff0c;各种缺依赖&#xff1b;其实最简单就是换操作系统&#xff0c;Ubuntu&#xff0c;centos停止维护之后我们现在服务器基本上都是Ubuntu;而我的环境又不想再折腾&#xff0c;…

网络应用技术 实验二:交换机VLAN 应用(华为ensp)

目录 一、实验简介 二、实验目的 三、实验需求 四、实验拓扑 五、实验任务及要求 1、任务 1&#xff1a;在交换机上创建VLAN 并测试通信 2、任务 2&#xff1a;路由交换机实现VLAN 之间通信 六、实验步骤 1、完成任务 1 2、完成任务 2 一、实验简介 在交换机上配置 VLAN&#x…

数学期望和联合概率密度

数学期望的定义 数学期望是描述随机变量平均趋势的一个重要统计量。根据随机变量的类型&#xff08;离散或连续&#xff09;&#xff0c;数学期望的定义有所不同。 离散型随机变量的数学期望&#xff1a; 若离散型随机变量 X X X取值为 x 1 , x 2 , … , x n , … x_1,x_2,\do…

Python基础学习(十)面向对象编程(基础)

代码获取&#xff1a;https://github.com/qingxuly/hsp_python_course 完结版&#xff1a;Python基础学习&#xff08;完结版&#xff09; 面向对象编程&#xff08;基础&#xff09; 类与对象 类与实例的关系 类与实例的关系示意图 快速入门—面向对象的方式解决养猫问题 …

.bixi勒索病毒来袭:如何防止文件加密与数据丢失?

导言 在网络威胁剧烈的今天&#xff0c;勒索病毒已成为企业和个人面临的重大安全挑战&#xff0c;其中虫洞勒索病毒习得高强度的加密手段和急剧传播的特性引起关注。一旦感染&#xff0c;就会加密关键数据并索要赎金&#xff0c;导致数据无法访问并带来巨大的财务损失。更为严…

OpenCV基础02_图像预处理

图像预处理 在计算机视觉和图像处理领域&#xff0c;图像预处理是一个重要的步骤&#xff0c;它能够提高后续处理&#xff08;如特征提取、目标检测等&#xff09;的准确性和效率。 OpenCV 提供了许多图像预处理的函数和方法&#xff0c;一些常见的图像预处理操作&#xff1a…

ctf文件上传题小总结与记录

解题思路&#xff1a;先看中间件&#xff0c;文件上传点&#xff08;字典扫描&#xff0c;会员中心&#xff09;&#xff0c;绕过/验证&#xff08;黑名单&#xff0c;白名单&#xff09;&#xff0c;解析漏洞&#xff0c;cms&#xff0c;编辑器&#xff0c;最新cve 文件上传漏…

安全成为大模型的核心;大模型安全的途径:大模型对齐

目录 安全成为大模型的核心 大模型安全的途径:大模型对齐 人类反馈强化学习(RLHF) 直接偏好优化(DPO) 安全成为大模型的核心 大模型安全的途径:大模型对齐 大模型对齐技术(Alignment Techniques for Large Language Models)是确保大规模语言模型(例如GPT-4)的输…

基于知识引导提示的因果概念提取(论文复现)

基于知识引导提示的因果概念提取(论文复现) 本文所涉及所有资源均在传知代码平台可获取 文章目录 基于知识引导提示的因果概念提取(论文复现)论文概述论文方法提示构造器获取典型概念集聚类典型概念构建训练数据训练主题分类器概念提取器输入构造指针网络置信度评分训练损失…

Rust的enum枚举的强大用法

在Rust中&#xff0c;enum&#xff08;枚举&#xff09;是一种非常强大的类型&#xff0c;它可以包含多个变体&#xff08;variants&#xff09;&#xff0c;每个变体可以是不同的类型&#xff0c;包括复杂类型。这使得enum在Rust中不仅用于表示简单的状态或选项集合&#xff0…

vue常用的修饰符有哪些

1、修饰符是什么 在Vue 中&#xff0c;修饰符处理了许多 DOM 事件的细节&#xff0c;让我们不再需要花大量的时间去处理这些烦恼的事情&#xff0c;而能有更多的精力专注于程序的逻辑处理 vue中修饰符分为以下五种 汇总修饰符说明表单lazy光标离开标签的时候&#xff0c;才会…

【创建型】单例模式

单例模式使用的场景&#xff1a;需要频繁的进行创建和销毁的对象、创建对象时耗时过多或耗费资源过多(即&#xff1a;重量级对象)&#xff0c;但又经常用到的对象、工具类对象、频繁访问数据库或文件的对象(比如数据源、session工厂等) 1. 饿汉式&#xff08;静态常量&#xf…

如何在Linux命令行中使用GhatGPT

2、验明正身&#xff0c;证明我的所在地是国内 3、第一次提问 4、第二次提问 5、问他一首古诗 6、话不多说&#xff0c;现在来展示他的安装过程 7、输入GitHub的网址 https://github.com/aandrew-me/tgpt 8、详情页向下翻 9、到终端输入 下列命令&#xff0c;等待安装&#x…

《机器人SLAM导航核心技术与实战》第1季:第10章_其他SLAM系统

视频讲解 【第1季】10.第10章_其他SLAM系统-视频讲解 【第1季】10.1.第10章_其他SLAM系统_RTABMAP算法 【第1季】10.2.第10章_其他SLAM系统_VINS算法 【第1季】10.3.第10章_其他SLAM系统_机器学习与SLAM 第1季&#xff1a;第10章_其他SLAM系统 先 导 课 第 1 季 &#xff…

比较36个结构的迭代次数

(A,B)---6*30*2---(0,1)(1,0) 让A是结构1&#xff0c;让B全是0。收敛误差为7e-4&#xff0c;收敛199次取迭代次数平均值&#xff0c;得到28080.98 做一个同样的网络(A,B)---6*30*2---(0,1)(1,0)&#xff0c;让A分是结构1-12&#xff0c;B全是0&#xff0c;用结构1的收敛权重做…