JVM虚拟机系统性学习-运行时数据区(方法区、程序计数器、直接内存)

方法区

方法区本质上是 Java 编译后代码的存储区域,存储了每一个类的结构信息,如:运行时常量池、成员变量、方法、构造方法和普通方法的字节码指令等内容

方法区主要存储的数据如下:

  • Class
    1. 类型信息,如该 Class 为 class 类、接口、枚举、注解,类的修饰符等等信息
    2. 方法信息(方法名称、方法返回值、方法参数等等)
    3. 字段信息:保存字段信息,如字段名称、字段类型、字段修饰符
    4. 类变量(静态变量):JDK1.7 之后转移到堆中存储
  • 运行时常量池(字符串常量池):JDK1.7 之后,转移到堆中存储
  • JIT 编译器编译之后的代码缓存

方法区的具体实现有两种:永久代(PermGen)、元空间(Metaspace)

  • JDK1.8 之前通过永久代实现方法区,JDK1.8 及之后使用元空间实现方法区
  • 这两种实现的不同,从存储位置来看:
    • 永久代使用的内存区域为 JVM 进程所使用的区域,大小受 JVM 限制
    • 元空间使用的内存区域为物理内存区域,大小受机器的物理内存限制
  • 从存储内容来看:
    • 永久代存储的信息上边方法区中规定的信息
    • 元空间只存储类的元信息,而静态变量和运行时常量池都转移到堆中进行存储

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

  • 字符串存在永久代中,容易出现性能问题和永久代内存溢出。
  • 类及方法的信息等比较难确定其大小,因此对于永久代的大小指定比较困难,太小容易出现永久代溢出,太大则容易导致老年代溢出。
  • 永久代会为 GC 带来不必要的复杂度,并且回收效率偏低。

常量池

  • class常量池:一个class文件只有一个class常量池

    字面量:数值型(int、float、long、double)、双引号引起来的字符串值等

    符号引用:Class、Method、Field等

  • 运行时常量池:一个class对象有一个运行时常量池

    字面量:数值型(int、float、long、double)、双引号引起来的字符串值等

    符号引用:Class、Method、Field等

  • 字符串常量池:全局只有一个字符串常量池

    双引号引起来的字符串值

程序计数器

程序计数器用于存储当前线程所执行的字节码指令的行号,用于选取下一条需要执行的字节码指令

分支,循环,跳转,异常处理,线程回复等都需要依赖这个计数器来完成

通过程序计数器,可以在线程发生切换时,可以保存该线程执行的位置

直接内存

直接内存(也成为堆外内存)并不是虚拟机运行时数据区的一部分,直接内存的大小受限于系统的内存

在 JDK1.4 引入了 NIO 类,在 NIO 中可以通过使用 native 函数库直接分配堆外内存,然后通过存储在堆中的 DirectByteBuffer 对象作为这块内存的引用进行操作

使用直接内存,可以避免了 Java 堆和 Native 堆中来回复制数据

直接内存使用场景:

  • 有很大的数据需要存储,且数据生命周期长
  • 频繁的 IO 操作,如网络并发场景

直接内存与堆内存比较:

  • 直接内存申请空间耗费更高的性能,当频繁申请到一定量时尤为明显
  • 直接内存IO读写的性能要优于普通的堆内存,在多次读写操作的情况下差异明显

直接内存相比于堆内存,避免了数据的二次拷贝。

  • 我们先来分析不使用直接内存的情况,我们在网络发送数据需要将数据先写入 Socket 的缓冲区内,那么如果数据存储在 JVM 的堆内存中的话,会先将堆内存中的数据复制一份到直接内存中,再将直接内存中的数据写入到 Socket 缓冲区中,之后进行数据的发送

    • 为什么不能直接将 JVM 堆内存中的数据写入 Socket 缓冲区中呢?

      在 JVM 堆内存中有 GC 机制,GC 后可能会导致堆内存中数据位置发生变化,那么如果直接将 JVM 堆内存中的数据写入 Socket 缓冲区中,如果写入过程中发生 GC,导致我们需要写入的数据位置发生变化,就会将错误的数据写入 Socket 缓冲区

  • 那么如果使用直接内存的时候,我们将数据直接存放在直接内存中,在堆内存中只存放了对直接内存中数据的引用,这样在发送数据时,直接将数据从直接内存取出,放入 Socket 缓冲区中即可,减少了一次堆内存到直接内存的拷贝

在这里插入图片描述

直接内存与非直接内存性能比较:

public class ByteBufferCompare {public static void main(String[] args) {//allocateCompare(); //分配比较operateCompare(); //读写比较}/*** 直接内存 和 堆内存的 分配空间比较* 结论: 在数据量提升时,直接内存相比非直接内的申请,有很严重的性能问题*/public static void allocateCompare() {int time = 1000 * 10000; //操作次数,1千万long st = System.currentTimeMillis();for (int i = 0; i < time; i++) {//ByteBuffer.allocate(int capacity) 分配一个新的字节缓冲区。ByteBuffer buffer = ByteBuffer.allocate(2); //非直接内存分配申请}long et = System.currentTimeMillis();System.out.println("在进行" + time + "次分配操作时,堆内存 分配耗时:" +(et - st) + "ms");long st_heap = System.currentTimeMillis();for (int i = 0; i < time; i++) {//ByteBuffer.allocateDirect(int capacity) 分配新的直接字节缓冲区。ByteBuffer buffer = ByteBuffer.allocateDirect(2); //直接内存分配申请}long et_direct = System.currentTimeMillis();System.out.println("在进行" + time + "次分配操作时,直接内存 分配耗时:" +(et_direct - st_heap) + "ms");}/*** 直接内存 和 堆内存的 读写性能比较* 结论:直接内存在直接的IO 操作上,在频繁的读写时 会有显著的性能提升*/public static void operateCompare() {int time = 10 * 10000 * 10000; //操作次数,10亿ByteBuffer buffer = ByteBuffer.allocate(2 * time);long st = System.currentTimeMillis();for (int i = 0; i < time; i++) {// putChar(char value) 用来写入 char 值的相对 put 方法buffer.putChar('a');}buffer.flip();for (int i = 0; i < time; i++) {buffer.getChar();}long et = System.currentTimeMillis();System.out.println("在进行" + time + "次读写操作时,非直接内存读写耗时:" +(et - st) + "ms");ByteBuffer buffer_d = ByteBuffer.allocateDirect(2 * time);long st_direct = System.currentTimeMillis();for (int i = 0; i < time; i++) {// putChar(char value) 用来写入 char 值的相对 put 方法buffer_d.putChar('a');}buffer_d.flip();for (int i = 0; i < time; i++) {buffer_d.getChar();}long et_direct = System.currentTimeMillis();System.out.println("在进行" + time + "次读写操作时,直接内存读写耗时:" +(et_direct - st_direct) + "ms");}
}

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

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

相关文章

人工智能在安全领域的应用

ChatGPT 等 AI 应用在网络安全领域的应用效果明显&#xff0c;其自动编程能力、分析能力及自身集成的知识库能够帮助网络安全从业者提升工作效率&#xff0c;改进组织的网络安全计划。 &#xff08;一&#xff09;代码生成与检测能力 可用于开发漏洞挖掘工具。如目前可以利用…

欧拉函数与欧拉定理

文章目录 AcWing 873. 欧拉函数题目链接欧拉函数欧拉函数的证明思路CODE时间复杂度分析 AcWing 874. 筛法求欧拉函数题目链接问题分析与时间复杂度CODE思路 欧拉定理 AcWing 873. 欧拉函数 题目链接 https://www.acwing.com/activity/content/problem/content/942/ 欧拉函数 …

Keil新建STM32软件工程 - (详细步骤图文)

文章目录 1. 前言2. 下载芯片对应的Keil开发包3. 下载芯片对应的标准外设库 - STM32F10x_StdPeriph_Lib_Vx.x.x4. 新建工程文件夹 - Demo34.1 移植标准外设库4.2 启动文件介绍及如何选择 5. 新建软件工程 - Demo5.1 打开Keil → Project → New uVision Project5.2 选择芯片型号…

从头到尾的数据之旅

目录 引言 链表介绍 单向链表的接口实现 结构 创建节点 头插 尾插 头删 尾删 打印 节点查找 节点前插入 节点删除 内存释放 总结 引言 在前面的学习中&#xff0c;我们深入了解了顺序表&#xff0c;通过其增删查改的操作&#xff0c;我们发现了顺序表在某些情况…

如何批量给文件名加相同字段?

如何批量给文件名加相同字段&#xff1f;文件名批量修改是一项蕴藏了非常多知识的电脑操作技能&#xff0c;批量修改文件名称不仅仅是修改名称这么简单&#xff0c;有时候我们还可能需要批量王文件名称中添加一些相同的文字字段&#xff0c;批量操作注重的是高效率&#xff0c;…

《Vue.js设计与实现》—Vue3响应系统的原理

一、响应式数据与副作用函数 1. 副作用函数 1-1 指令材料 在JavaScript中&#xff0c;副作用函数是指在执行过程中对外部环境产生可观察的变化或影响的函数。这种函数通常会修改全局变量、修改传入的参数、执行I/O操作&#xff08;如读写文件或发送网络请求&#xff09;、修…

论文阅读《Learning Adaptive Dense Event Stereo from the Image Domain》

论文地址&#xff1a;https://openaccess.thecvf.com/content/CVPR2023/html/Cho_Learning_Adaptive_Dense_Event_Stereo_From_the_Image_Domain_CVPR_2023_paper.html 概述 事件相机在低光照条件下可以稳定工作&#xff0c;然而&#xff0c;基于事件相机的立体方法在域迁移时性…

【教程】开始使用ipaguard进行代码加固混淆

开始使用ipaguard 前言 iOS加固保护是直接针对ios ipa二进制文件的保护技术&#xff0c;可以对iOS APP中的可执行文件进行深度混淆、加密。使用任何工具都无法逆向、破解还原源文件。对APP进行完整性保护&#xff0c;防止应用程序中的代码及资源文件被恶意篡改。Ipa Guard通过…

springMVC 学习总结(三) 拦截器及统一异常处理

一.拦截器 1.拦截器与过滤器的区别 拦截器 Interceptor 和 过滤器 Filter类似&#xff0c;主要用于拦截用户请求并作出一定处理操作&#xff0c; 但两则也有不同之处&#xff0c;如过滤器只在Servlet前后起作用&#xff0c;是Servlet规范定义的&#xff0c;是Servlt容器才支…

NGINX高性能服务器与关键概念解析

目录 1 NGINX简介2 NGINX的特性3 正向代理4 反向代理5 负载均衡6 动静分离7 高可用8 结语 1 NGINX简介 NGINX&#xff08;“engine x”&#xff09;在网络服务器和代理服务器领域备受推崇。作为一款高性能的 HTTP 和反向代理服务器&#xff0c;它以轻量级、高并发处理能力以及…

2-1基础算法-枚举/模拟

文章目录 1.枚举2.模拟 1.枚举 [例1] 特别数的和 评测系统 #include <iostream> using namespace std; bool pa(int x) {while (x) {if (x % 10 2 || x % 10 1 || x % 10 0 || x % 10 9) {return true;}else {x x / 10;}}return false; } int main() {int sum0;i…

【pytest】单元测试文件的写法

前言 可怜的宾馆&#xff0c;可怜得像被12月的冷雨淋湿的一条三只腿的黑狗。——《舞舞舞》 \;\\\;\\\; 目录 前言test_1或s_test格式非测试文件pytest.fixture()装饰器pytestselenium test_1或s_test格式 要么 test_前缀 在前&#xff0c;要么 _test后缀 在后&#xff01; …

低压无功补偿在分布式光伏现场中的应用

摘要&#xff1a;分布式光伏电站由于建设时间短、技术成熟、收益明显而发展迅速&#xff0c;但光伏并网引起用户功率因数异常的问题也逐渐凸显。针对分布式光伏电站接入配电网后功率因数降低的问题&#xff0c;本文分析了低压无功补偿装置补偿失效的原因&#xff0c;并提出了一…

代码随想录算法训练营第46天| 139.单词拆分 多重背包

JAVA代码编写 139.单词拆分 给你一个字符串 s 和一个字符串列表 wordDict 作为字典。请你判断是否可以利用字典中出现的单词拼接出 s 。 **注意&#xff1a;**不要求字典中出现的单词全部都使用&#xff0c;并且字典中的单词可以重复使用。 示例 1&#xff1a; 输入: s &…

Java - JVM内存模型及GC(垃圾回收)机制

JVM内存模型 JVM堆内存划分&#xff08;JDK1.8以前&#xff09; JVM堆内存划分&#xff08;JDK1.8之后&#xff09; 主要变化在于&#xff1a; java8没有了永久代&#xff08;虚拟内存&#xff09;&#xff0c;替换为了元空间&#xff08;本地内存&#xff09;。常量池&#…

数据库中常用的锁

目录 1、数据库中常用的锁类型 2、常见的数据库 3、以MySQL为例 3.1 MySQL的事务 3.2 MySQL事务的四大特性 1. 原子性&#xff08;Atomicity&#xff09; 2. 一致性&#xff08;Consistency&#xff09; 3. 隔离性&#xff08;Isolation&#xff09; ⭐mysql中的事务隔…

temu上传产品的素材哪里找

在为Temu&#xff08;拼多多跨境电商平台&#xff09;上传产品时&#xff0c;您需要准备一些高质量的素材&#xff0c;包括图片和视频。这些素材对于吸引用户的注意力、展示产品的特点以及提高购买意愿非常重要。但是&#xff0c;很多卖家都不知道从哪里找到这些素材。本文将为…

【Deeplearning4j】小小的了解下深度学习

文章目录 1. 起因2. Deeplearning4j是什么3. 相关基本概念4. Maven依赖5. 跑起来了&#xff0c;小例子&#xff01;6. 鸢尾花分类代码 7. 波士顿房价 回归预测代码 8. 参考资料 1. 起因 其实一直对这些什么深度学习&#xff0c;神经网络很感兴趣&#xff0c;之前也尝试过可能因…

Unity-小工具-LookAt

Unity-小工具-LookAt &#x1f959;介绍 &#x1f959;介绍 &#x1f4a1;通过扩展方法调用 gameObject.LookAtTarget&#xff0c;让物体转向目标位置 &#x1f4a1;gameObject.StopLookat 停止更新 &#x1f4a1;可以在调用时传入自动停止标记&#xff0c;等转向目标位置后自…

.net 洋葱模型

洋葱架构 内层部分比外层更抽象(内层接口&#xff0c;外层实现)。外层的代码只能调用内层的代码&#xff0c;内层的代码可以通过依赖注入的形式来间接调用外层的代码 简单的例子&#xff0c;引用依赖图 demo 接口类库 EmailInfo using System; using System.Collections.…