JVM 性能调优 - Java 虚拟机内存体系(1)

Java 虚拟机我们简称为 JVM(Java Virtual Machine)。

Java 虚拟机在执行 Java 程序的过程中,会管理几个不同的数据区域。如下图所示:

下面我会介绍这几个数据区的特点。

堆区的几个特点:

  • 线程共享。
  • 启动时创建堆这个区。
  • 基本上所有的对象实例都在这个区分配。
  • 物理上不连接(大对象除外)。逻辑上不连接。
  • 内存分为新生代和老年代。新生代分为 eden 区和两个大小一样的 survivor 区。

内存细分:

Java 7 及之前内存逻辑上分为三部分:新生区 + 老年代 + 永久代。

  • 新生区,又被划分为 Eden 区和 Survivor 区。
  • 老年代。
  • 永久代实现了方法区。

Java 8 及之后内存逻辑上分为三部分:新生区 + 老年代 + 元空间。

  • 新生区,又被划分为 Eden 区和 Survivor 区。
  • 老年代。
  • 废弃了永久代,使用元空间,它属于本地内存。
方法区
  • 线程共享。
  • 主要存储这几类信息。
    • 类型信息。
    • 常量。
    • 静态变量。
    • 即时编译器编译后的代码缓存。
虚拟机栈
  • 线程私有。
  • 生命周期与线程相同。
  • 一个线程中,每一个方法被执行的时候,创建一个栈帧。
  • 栈帧 Stack Frame 的结构。
    • 存储局部变量表。
      • 基本数据类型。
      • 对象引用。
      • 返回地址(returnAddress)。
    • 操作数栈。
    • 动态连接。
    • 方法出口。
本地方法栈
  • 线程私有。

  • 虚拟机使用到的本地(Native)方法服务。

程序计数器
  • 线程私有。

  • 当前线程所执行的字节码的行号指示器。

几个数据区的特点思维导图

垃圾回收

垃圾回收主要关注方法区和堆中的垃圾收集。如下图所示,方法区和堆被高亮显示,用来说明垃圾收集器关心的收集区域。

收集堆区域是垃圾收集器的工作重点。上面我们也讲到了堆空间的划分,包含新生代和老年代,而垃圾收集器会频繁收集新生代,较少收集老年代。

什么是垃圾

我们可以先想下现实生活中的垃圾,比如吃香蕉后的香蕉皮,我们不需要就扔到垃圾桶了,那么香蕉皮就属于垃圾,需要被环卫工人回收。 那 Java 虚拟机中,什么是垃圾呢?

垃圾是指在运行程序中没有任何指针指向的对象,这些对象被当作垃圾被垃圾收集器回收。

如何确定垃圾

有两种算法来确定哪些对象是垃圾:引用计数法和根节点可达性分析。

  • 引用计数法

原理:给对象添加一个引用计数器,每当有一个地方引用它,计数器的值就加一。每当有一个引用失效,计数器的值就减一。当计数器值为零时,这个对象被认为没有其他对象引用,可当作垃圾回收。

缺点:需要维护引用计数器,有一定的消耗。且较难处理循环引用的问题。(现在基本没有地方使用这种算法了,了解即可)。

  • 可达性分析算法

原理:通过一系称为 GC Roots 的对象作为起始点,从 GC Roots 的对象出发,向下搜索,如果找到的对象和 GC Roots 有直接引用或间接引用关系,则说明这个对象不是垃圾,否则,这个对象就是垃圾。

哪些对象可以当作 GC Roots
  • 虚拟机栈中的引用对象。
  • 方法区中的类静态属性引用的对象。
  • 方法区中常量引用的对象。
  • 本地方法栈中的 JNI(Native 方法)引用的对象。

总结:除了堆空间外的一些结构,比如虚拟机栈、本地方法栈、方法区、字符串常量池等地方对堆空间进行引用的,都可以作为 GC Roots 进行可达性分析。

GC Roots 对象回收

编写程序

package com.test;public class TestGCRoots {private static final int _1MB = 1024 * 1024;private byte[] bigSize = new byte[2 * _1MB];private static TestGCRoots testGCRoots;public static void main(String[] args) throws InterruptedException {testGCRoots = new TestGCRoots();//gcRootsDemo = null;System.gc();}
}

运行程序

$ java -XX:+PrintGCDetails com.test.TestGCRoots
[GC (System.gc()) [PSYoungGen: 5980K->2904K(114176K)] 5980K->2912K(375296K), 0.0024028 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (System.gc()) [PSYoungGen: 2904K->0K(114176K)] [ParOldGen: 8K->2689K(261120K)] 2912K->2689K(375296K), [Metaspace: 2672K->2672K(1056768K)], 0.0049802 secs] [Times: user=0.13 sys=0.00, real=0.00 secs]
Heap
 PSYoungGen      total 114176K, used 983K [0x0000000740b80000, 0x0000000748a80000, 0x00000007c0000000)
  eden space 98304K, 1% used [0x0000000740b80000,0x0000000740c75da0,0x0000000746b80000)
  from space 15872K, 0% used [0x0000000746b80000,0x0000000746b80000,0x0000000747b00000)
  to   space 15872K, 0% used [0x0000000747b00000,0x0000000747b00000,0x0000000748a80000)
 ParOldGen       total 261120K, used 2689K [0x0000000642200000, 0x0000000652100000, 0x0000000740b80000)
  object space 261120K, 1% used [0x0000000642200000,0x00000006424a07d8,0x0000000652100000)
 Metaspace       used 2679K, capacity 4486K, committed 4864K, reserved 1056768K
  class space    used 289K, capacity 386K, committed 512K, reserved 1048576K

断开实例引用

package com.test;public class TestGCRoots {private static final int _1MB = 1024 * 1024;private byte[] bigSize = new byte[2 * _1MB];private static TestGCRoots testGCRoots;public static void main(String[] args) throws InterruptedException {testGCRoots = new TestGCRoots();gcRootsDemo = null;System.gc();}
}

运行程序

$ java -XX:+PrintGCDetails com.test.TestGCRoots
[GC (System.gc()) [PSYoungGen: 5980K->872K(114176K)] 5980K->880K(375296K), 0.0012472 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (System.gc()) [PSYoungGen: 872K->0K(114176K)] [ParOldGen: 8K->641K(261120K)] 880K->641K(375296K), [Metaspace: 2674K->2674K(1056768K)], 0.0063510 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
Heap
 PSYoungGen      total 114176K, used 983K [0x0000000740b80000, 0x0000000748a80000, 0x00000007c0000000)
  eden space 98304K, 1% used [0x0000000740b80000,0x0000000740c75da0,0x0000000746b80000)
  from space 15872K, 0% used [0x0000000746b80000,0x0000000746b80000,0x0000000747b00000)
  to   space 15872K, 0% used [0x0000000747b00000,0x0000000747b00000,0x0000000748a80000)
 ParOldGen       total 261120K, used 641K [0x0000000642200000, 0x0000000652100000, 0x0000000740b80000)
  object space 261120K, 0% used [0x0000000642200000,0x00000006422a07b8,0x0000000652100000)
 Metaspace       used 2681K, capacity 4486K, committed 4864K, reserved 1056768K
  class space    used 289K, capacity 386K, committed 512K, reserved 1048576K

对象和 GC Roots 没有引用关系时(这里引用关系可以是间接或直接引用),即对象不可达,将会被垃圾收集器标记为垃圾,后期被回收掉。

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

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

相关文章

Vue ElementUI中el-table表格嵌套样式问题

一、表格嵌套要求: 两个表格嵌套,当父表格有children数组时子表格才展示;子表格数据少于父表格展示字段,且对应固定操作列不同; 二、嵌套问题: 当使用el-table的typeexpand实现表格嵌套时,样…

Rouge评估方法介绍及使用

Rouge评估方法的使用 文本摘要评估方法介绍: 内部评价方法:提供参考摘要,以参考摘要为基准评价系统摘要的质量。系统摘要与参考摘要越吻合,质量越高。 Edmundson: 适于抽取式文本摘要,比较机械文摘(自动文摘系统得到的…

配置Jenkins自动构建打包项目

转载说明:如果您喜欢这篇文章并打算转载它,请私信作者取得授权。感谢您喜爱本文,请文明转载,谢谢。 需求说明 1、给A项目配置jenkins每2小时无条件自动构建一次,无论是否有代码提交。 2、给B项目配置jenkins每15分钟检…

Spring Data Envers 数据审计实战2 - 自定义监听程序扩展审计字段及字段值

上篇讲述了如何在Spring项目中集成Spring Data Envers做数据审计和历史版本查看功能。 之前演示的是业务表中已有的字段进行审计,那么如果我们想扩展审计字段呢? 比如目前对员工表加入了Audited审计,员工表有个字段为dept_id,为…

私有化部署跳一跳

目录 效果 安装 1.安装httpd 2.下载跳一跳 3.启动httpd 使用 效果 安装 1.安装httpd yum -y install httpd systemctl enable httpd 2.下载跳一跳 cd /var/www/html/ git clone https://gitee.com/WangZhe168_admin/jump.git 3.启动httpd systemctl start httpd 使…

vue-3d-loader

vue-3d-loader - npm GitHub - king2088/vue-3d-loader: VueJS and threeJS 3d viewer 是对 vue-3d-model 的改进,降低Threejs使用难度 # 默认安装 "vue-3d-loader": "^1.3.4", 只支持vue2 npm i vue-3d-loader # vue3 需要安装2版本&#xf…

Kafka 生产调优

Kafka生产调优 文章目录 Kafka生产调优一、Kafka 硬件配置选择场景说明服务器台数选择磁盘选择内存选择CPU选择 二、Kafka Broker调优Broker 核心参数配置服役新节点/退役旧节点增加副本因子调整分区副本存储 三、Kafka 生产者调优生产者如何提高吞吐量数据可靠性数据去重数据乱…

算法day11

算法day11 239 滑动窗口最大值237 前K个高频元素栈与队列总结 滑动窗口最大值 第一想法,暴力解:这个解法会超时。(这就是为啥是困难题) 思路:每到一个新的窗口,就重新进行一次窗口中的max迭代&#xff0c…

ubuntu22.04@laptop OpenCV Get Started: 000_hello_opencv

ubuntu22.04laptop OpenCV Get Started: 000_hello_opencv 1. 源由2. Hello OpenCV2.1 C应用Demo2.2 Python应用Demo 3. 参考资料 1. 源由 之前,通过敲门砖已经砸开了OpenCV的大门,接下来是体验下“Hello World!”程序。 2. Hello OpenCV …

HarmonyOS鸿蒙ArkTS证件照生成模板(适合二次开发,全套源码版)

预览效果 部分代码 开发语言 HarmonyOS 鸿蒙 ArkTS语言 (Stage模型) 备注 一键生成,自带证件照数集, 为开发者带来二次开发和学习体验, 在这祝福开发者们使用愉快。 使用方法 下载后通过DevEco Studio开发工…

物联网ARM开发-STM32之RTC浅谈

RTC 一.RTC简单介绍 RTC好比我们用来记录时间的一个钟表,他里面有年月日,还可以记录星期,小时,分钟等。是Real Time Clock的缩写,译为实时时钟,本质上是一个独立的定时器。 1. 1 与通用定时器的区别 可以…

EEPROM之MB85RC64介绍

一、芯片介绍 工作频率 : 400 kHz (最大) 即,当主机和一个EEPROM通信时,从机地址为1010 000WR,如果主机和多个EEPROM通信时,从机地址为1010 A2 A1 A0 WR 二、时序分析 (1)从机地址…

适用于 Windows 和 Mac 的 16 款最佳数据恢复软件

数据恢复软件是找回因硬盘损坏、病毒攻击或意外删除数据等原因而在设备上丢失的数据的最佳方法。在数字世界中,丢失数据是一件非常糟糕的事情,这会让许多人的情况变得更糟。使用最佳数据恢复软件可以减轻您必须努力恢复丢失数据的压力。它将带回您的大部…

C# OpenCvSharp DNN 部署yolov4目标检测

目录 效果 项目 代码 下载 效果 项目 代码 using OpenCvSharp; using OpenCvSharp.Dnn; using System; using System.Collections.Generic; using System.Drawing; using System.IO; using System.Linq; using System.Windows.Forms;namespace OpenCvSharp_DNN_Demo {publ…

Linux环境下配置mysql主从复制

主从配置需要注意的地方 1、主DB server和从DB server数据库的版本一致 2、主DB server和从DB server数据库数据一致[这里就会可以把主的备份在从上还原,也可以直接将主的数据目录拷贝到从的相应数据目录] 3、主DB server开启二进制日志,主DB server和从DB serve…

二分查找------蓝桥杯

题目描述&#xff1a; 请实现无重复数字的升序数组的二分查找 给定一个元素升序的、无重复数字的整型数组 nums 和一个目标值 target&#xff0c;写一个函数搜索 nums 中的target&#xff0c;如果目标值存在返回下标 (下标从0 开始)&#xff0c;否则返回-1 数据范围: 0 < l…

分布式文件存储系统minio

参考Linux搭建免费开源对象存储 wget https://dl.minio.io/server/minio/release/linux-amd64/minio yum install -y wget yum install -y wget wget https://dl.minio.io/server/minio/release/linux-amd64/minio chmod x minio sudo mv minio /usr/local/bin/ minio --vers…

外汇天眼:外汇天眼:注意,19个外汇平台因诈骗被监管拉黑!

近年来&#xff0c;全球金融市场出现了众多非法投资平台&#xff0c;这些平台利用虚假宣传和高回报承诺欺骗投资者&#xff0c;造成了严重的经济损失。为了保护投资者利益&#xff0c;监管机构也在加大力度打击这些非法平台。就在最近&#xff0c;又有19个外汇交易平台因涉嫌诈…

【C语言 - 力扣 - 反转链表】

反转链表题目描述 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 题解1-迭代 假设链表为 1→2→3→∅&#xff0c;我们想要把它改成 ∅←1←2←3。 在遍历链表时&#xff0c;将当前节点的 next 指针改为指向前一个节点。由于节点没…

计算机网络-差错控制(纠错编码 海明码 纠错方法)

文章目录 纠错编码-海明码海明距离1.确定校验码位数r2.确定校验码和数据的位置3.求出校验码的值4.检错并纠错纠错方法1纠错方法2 小结 纠错编码-海明码 奇偶校验码&#xff1a;只能发现错误不能找到错误位置和纠正错误 海明距离 如果找到码距为1&#xff0c;那肯定为1了&…