回炉重造java----JVM

news2024/10/6 20:36:58

为什么要使用JVM

①一次编写,到处运行,jvm屏蔽字节码与底层的操作差异

②自动内存管理,垃圾回收功能

③数组下边越界检查

④多态

JDK,JRE,JVM的关系

JVM组成部分

JVM的内存结构

《一》程序计数器(PC Register)

作用:

java代码执行流程: java源代码-->二进制字节码文件(jvm指令)-->解释器-->机器码-->cpu执行,而程序计数器就是去记住下一条jvm指令的执行地址。

特点:

        ①线程私有

        ②唯一不会存在内存溢出的区

《二》虚拟机栈(JVM Stack)

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

        1. 答:垃圾回收不涉及栈内存,因为栈中是运行方法时的存放的地方,当方法结束后栈帧会自动退栈释放空间,不需要垃圾回收机制来处理。垃圾回收主要是去处理堆内存。

        2. 答:不是,内存分配越大并不会对程序的执行效率有提升,反而会减少内存空间和线程的数量。

        3. 答:方法内的局部变量是安全的,因为一个线程对应自己的一个栈,局部变量各自存在栈中。但是如果是static修饰的变量线程间就会共享,可能会产生线程安全问题。另外如果局部变量是引用类型并且逃离了方法的作用范围,就会产生线程安全问题。

栈内存溢出:java.lang.StackOverflowError

        ①方法(栈帧)过多,栈帧内存超过栈的总内存就会发生栈溢出 

        ②栈帧过大直接挤满了栈发生栈溢出(反复调用)

 线程诊断:

        ①top命令可以查看所有正在运行的进行和系统负荷提供不断更新的概览信息,包括系统负载、CPU利用分布情况、内存使用、每个进程的资源占用情况等信息

        ②ps H -eo pid,tid,%cpu |  grep 进程ID    查看线程的信息

        ③jstack 进程ID  查看进程的线程信息

        

《三》本地方法栈(Native Method Stacks)

        有的时候我们需要调用操作系统底层的一些方法,但是java语言不可以直接调用,所以就需要一些更底层的c或者c++写的本地方法去间接调用。所以我们要创建一个本地方法栈去存储本地方法运行时需要的空间

        

《四》堆(Heap)

        ①通过new 创建的对象都会使用堆内存

        ②线程共享,其中的对象都需要考虑线程安全的问题

        ③垃圾回收机制

堆内存溢出: java.lang.OutOfMemoryError

堆内存诊断:

        ①jps   查看当前正在运行的java进程

        ②jmap -heap 进程号   查看堆内存的占用情况

        ③jconsole

《五》方法区(Method Area)

        ①线程共享,在虚拟机启动时创建

        ②ClassLoader,类加载器,加载类的二进制字节码

 方法区内存溢出:

运行时常量池 

①二进制字节码文件:类的基本信息+常量池+类方法定义包括虚拟机指令

②常量池:是.class文件中的,其实就是一张表,虚拟机指令根据常量池去找到要执行对应的类名,方法名,参数等信息

③运行时常量池:当类被加载时他的常量池信息就会放进运行时常量池,并且把其中的符号地址编程真实地址

StringTable串池(hashtable结构,不能扩容)

常量池被加载到运行时常量池的时候,这时 a b ab 都是常量池中的符号,还不是java对象。当程序中要使用的时候会先去查看串池中有没有,没有的话就把这些符号放到串池当中变成字符串对象。这个是叫做字符串的延迟加载,不用就不加载

s1+s2会在堆中创建一个新的字符串对象。其底层是一个StringBuilder对象,使用toString方法最后再new String对象,注意:这个对象是只在堆中,不在串池中

s5中,两个字符串拼接起来是直接在串池中找

注意,1.6版本的话如果串池中没有的话,会复制一份对象放进去,而不是放本身,所以串池中的对象跟外面的那个不是一个,外面那个对象还是在堆中

来个题目练练手:

StringTable的位置:1.6下存放在常量池(永久代)中,1.7之后就放在堆中,因为在常量池中的回收效率很低 

StringTable垃圾回收

当存入的数据大于Stringtable的空间大小时,会触发垃圾回收机制

StringTable性能调优

①参数StringTableSize来调整StringTable的桶个数,让下面的链表不能太长

②当有大量的字符串对象时,考虑将字符串对象是否入池,去重优化字符串的个数

《六》垃圾回收

1,如何判断对象可以回收:

        ①引用计数法

        ②可达性分析算法,这个算法的基本思想就是通过一系列的称为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链,当一个对象到 GC Roots 没有任何引用链相连时,则证明此对象是不可用的。

        ③Java的五种引用

2,垃圾回收算法

标记—清除:分为两个阶段,一个是标记阶段,为每个对象进行标记看是不是被GC ROOT引用;第二个阶段是清除阶段,该阶段对死亡的对象进行清除,执行 GC 操作。

        优点:是可以解决循环引用的问题必要时才回收(内存不足时)

        缺点:标记和清除的效率不高,尤其是要扫描的对象比较多的时候,会造成内存碎片

标记—整理:也是分为两个阶段,一个是标记阶段,为每个对象进行标记看是不是被GC ROOT引用;第二个阶段是整理,在清理垃圾的过程中将所有存活的对象整理移动一下,再去清理空间

        优点:解决标记清除算法出现的内存碎片问题。

        缺点:压缩阶段,由于移动了可用对象,需要去更新引用。

复制算法:将内存分成两个相同大小的区,分别为from和to。使用时只使用一个,当进行垃圾回收时,首先将from区的垃圾标记,然后把存活的对象全部放去to区,再清空from区,执行完之后把二者身份互换。

        优点:能解决内存碎片

        缺点::会造成一部分的内存浪费;如果存活对象的数量比较大,复制算法的性能会变得很差。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

记录MySQL数据库查询不等于xxx时的坑

目录 一、背景 二、需求 三、方法 四、示例 一、背景 在使用MySQL数据库查询数据时,需要查询字段name不等于xxx的记录,通过where name ! xxx查询出来的记录不符合预期,通过检查发现少了name字段为null的记录,后经查询得知在My…

Python | Leetcode Python题解之第88题合并两个有序数组

题目: 题解: class Solution:def merge(self, nums1: List[int], m: int, nums2: List[int], n: int) -> None:"""Do not return anything, modify nums1 in-place instead."""p1, p2 m - 1, n - 1tail m n - 1whi…

【吃透Java手写】5-RPC-简易版

【吃透Java手写】RPC-简易版-源码解析 1 RPC1.1 RPC概念1.2 常用RPC技术或框架1.3 初始工程1.3.1 Productor-common:HelloService1.3.2 Productor:HelloServiceImpl1.3.3 Consumer 2 模拟RPC2.1 Productor2.2 模拟一个RPC框架2.2.1 HttpServer2.2.2 Http…

Elasticsearch解决字段膨胀问题

文章目录 背景Flattened类型的产生Flattened类型的定义基于Flattened类型插入数据更新Flattened字段并添加数据Flattened类型检索 Flattened类型的不足 背景 Elasticsearch映射如果不进行特殊设置,则默认为dynamic:true。dynamic:true实际上支持不加约束地动态添加…

【AI大模型】自动生成红队攻击提示--GPTFUZZER

本篇参考论文为: Yu J, Lin X, Xing X. Gptfuzzer: Red teaming large language models with auto-generated jailbreak prompts[J]. arXiv preprint arXiv:2309.10253, 2023. https://arxiv.org/pdf/2309.10253 一 背景 虽然LLM在今天的各个领域得到了广泛的运用…

AI办公自动化-用kimi自动清理删除重复文件

在kimichat中输入提示词: 你是一个Python编程专家,要完成一个编写Python脚本的任务,具体步骤如下: 1、打开文件夹D:\downloads; 2、哈希值比较比较里面所有的文件,如果文件相同,那么移动多余…

3D Gaussian Splatting for Real-Time Radiance Field Rendering 论文阅读

如此热门的项目,网络上有很多大牛分析了这篇文章的做法,在这里简单记录一下个人粗浅的理解。 关于各种数学表达式的推导,论文和参考资料中都提供了较为详细的解读,本人能力有限,这一部分理解不够深刻,先不做…

绝地求生:艾伦格回归活动来了,持续近1个月,新版本皮肤、G币等奖励白嫖

嗨,我是闲游盒~ 29.2版本更新在即,新活动来啦!目前这个活动国内官方还没发,我就去台湾官方搬来了中文版方便大家观看,也分析一下这些奖励应该怎样才能获得。 新版本将在周二进行约9小时的停机维护,请注意安…

centos7中如何优雅的动态切换jdk版本?

在 CentOS 7 中动态切换 JDK 版本可以通过多种方法实现,其中最常见的方法是使用 alternatives 命令,这是 CentOS 和其他基于 Red Hat 的系统中用于管理多个软件版本的标准工具。下面我会详细介绍如何使用 alternatives 命令来切换 JDK 版本。 步骤 1: 安…

如何通过 AWS Managed Apache Flink 实现 Iceberg 的实时同步

AWS Managed Apache Flink (以下以 MAF 代指)是 AWS 提供的一款 Serverless 的 Flink 服务。 1. 问题 大家在使用 MAF 的时候,可能遇到最大的一个问题就是 MAF 的依赖管理,很多时候在 Flink 上运行的代码,托管到 MAF…

[Algorithm][回溯][找出所有子集的异或总和再求和][全排列 II][电话号码的字母组合][括号生成]详细讲解

目录 1.找出所有子集的异或总和再求和1.题目链接2.算法原理详解3.代码实现 2.全排列 II1.题目链接2.算法原理详解3.代码实现 3.电话号码的字母组合1.题目链接2.算法原理详解3.代码实现 4.括号生成1.题目链接2.算法原理详解3.代码实现 1.找出所有子集的异或总和再求和 1.题目链…

PCIE协议-2-事务层规范-TLP Prefix Rules

2.2.10 TLP前缀规则 以下规则适用于任何包含TLP前缀的TLP: 对于任何TLP,TLP中byte0的Fmt[2:0]字段中的值100b表示存在TLP前缀,并且Type[4]位指示TLP前缀的类型。 Type[4]位中的值0b表示存在本地TLP前缀。Type[4]位中的值1b表示存在端到端TL…

数据结构与算法-排序算法1-冒泡排序

本文先介绍排序算法,然后具体写冒泡排序。 目录 1.排序算法简介 2.常见的排序算法分类如下图: 3.冒泡排序: 1.介绍: 2.动态图解 3.举例 4.小结冒泡排序规则 5.冒泡排序代码 6.优化 7.优化后时间 代码: 运…

Java | Leetcode Java题解之第88题合并两个有序数组

题目: 题解: class Solution {public void merge(int[] nums1, int m, int[] nums2, int n) {int p1 m - 1, p2 n - 1;int tail m n - 1;int cur;while (p1 > 0 || p2 > 0) {if (p1 -1) {cur nums2[p2--];} else if (p2 -1) {cur nums1[p…

Vue的学习 —— <vue指令>

目录 前言 正文 内容渲染指令 内容渲染指令的使用方法 v-text v-html 属性绑定指令 双向数据绑定指令 事件绑定指令 条件渲染指令 循环列表渲染指令 侦听器 前言 在完成Vue开发环境的搭建后,若想将Vue应用于实际项目,首要任务是学习Vue的基…

黑马基于Web-socket的java聊天室基本解析

要是用Web-socket协议&#xff0c;我们要前端upgrade升级成web-socket协议 首先我们要引入springboot的websocket起步依赖&#xff0c;这样子方便使用&#xff0c;自己指定版本注意 <dependency><groupId>org.springframework.boot</groupId><artifactId&…

绘唐3启动器怎么启动一键追爆款3正式版

绘唐3启动器怎么启动一键追爆款3正式版 工具入口 一.文案助手&#xff1a; 【注意&#xff01;&#xff01;】如果图片无显示&#xff0c;一般情况下被杀毒拦截&#xff0c;需关闭杀毒软件或者信任文件路径。 win10设置排除文件&#xff1a; 1.【新建工程】使用前先新建工程…

std::ref和std::cref的使用和原理分析

目录 1.用法 2.std::reference_wrapper介绍 3.std::ref原理分析 4.std::cref原理分析 5.总结 1.用法 它的定义如下&#xff1a; std::ref&#xff1a;用于包装按引用传递的值。 std::cref&#xff1a;用户包装按const引用传递的值。 C本身就有引用&#xff08;&&#…

使用 Python 中的 TensorFlow 检测垃圾短信

前言 系列专栏&#xff1a;机器学习&#xff1a;高级应用与实践【项目实战100】【2024】✨︎ 在本专栏中不仅包含一些适合初学者的最新机器学习项目&#xff0c;每个项目都处理一组不同的问题&#xff0c;包括监督和无监督学习、分类、回归和聚类&#xff0c;而且涉及创建深度学…

【鸿蒙开发】第二十四章 IPC与RPC进程间通讯服务

1 IPC与RPC通信概述 IPC&#xff08;Inter-Process Communication&#xff09;与RPC&#xff08;Remote Procedure Call&#xff09;用于实现跨进程通信&#xff0c;不同的是前者使用Binder驱动&#xff0c;用于设备内的跨进程通信&#xff0c;后者使用软总线驱动&#xff0c;…