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.hqwc.cn/news/454953.html

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

相关文章

L1-009 N个数求和-java

输入样例1: 5 2/5 4/15 1/30 -2/60 8/3输出样例1: 3 1/3输入样例2: 2 4/3 2/3输出样例2: 2输入样例3: 3 1/3 -1/6 1/8输出样例3: 7/24 这是使用递归的另一种计算最大公约数的方法。 如果 b 为0&#…

【从0上手Cornerstone3D】如何使用CornerstoneTools中的工具之同步器

同步器(Synchronizers)可以使多个视图同步响应同一个工具的操作,例如我们在MPR视图下,同步操作三个视图的缩放程度、windowLevel等等 一个同步器必须需要以下几个部分才可以执行 一个监听事件(什么情况下触发同步&…

3D力导向树插件-3d-force-graph学习001

一、引入文件:下载静态js文件引入 1、**以vue项目测试,在index.html文件中引入静态文件(js文件可在官网下载)** 2、**也曾尝试用npm包下载引入的方法,总是会有报错,所以采用静态js文件引入的方式** 二、基…

浅析软件测试中的一些常见理论:杀虫剂效应、金字塔模型、缺陷集群性原则、软件测试活动依赖于软件测试背景、软件测试的7大基本原则

这篇文章我主要想记录学习一下在软件测试行业中的一些常见理论效应以做基本了解。 一、杀虫剂效应 1、杀虫剂效应介绍 杀虫剂效应原本指农业中随着农药的普及使用,害虫对农药的抗药性就越来越强,农药就越来越难杀死害虫。在农场里为了对付破坏农作物的…

PyTorch 2.2 中文官方教程(九)

在生产环境中部署 PyTorch 模型 通过 Flask 在 Python 中部署 PyTorch 的 REST API 原文:pytorch.org/tutorials/intermediate/flask_rest_api_tutorial.html 译者:飞龙 协议:CC BY-NC-SA 4.0 注意 点击这里下载完整的示例代码 作者&#…

程序员为什么不喜欢关电脑,这回答很霸道!

在大家的生活中,经常会发现这样一个现象:程序员经常不关电脑。 至于程序员不关电脑的原因,众说纷纭。 其中这样的一个程序员,他的回答很霸道: “因为我是程序员,我有权选择不关电脑。我需要在任何时候都能够…

Spring IoC容器(三)注解

Spring 除了支持通过XML形式配置Bean外,也支持通过注解的形式来配置Bean。需要简洁、易于维护和低耦合度场景下,注解是更好的选择;需要可读性强、可扩展性和分离关注点的场景下,XML是一个更好的选择。 方式 优点 缺点 注解 简…

【网站项目】037物流管理系统

🙊作者简介:拥有多年开发工作经验,分享技术代码帮助学生学习,独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。🌹赠送计算机毕业设计600个选题excel文件,帮助大学选题。赠送开题报告模板&#xff…

windows安装Visual Studio Code,配置C/C++运行环境(亲测可行)

一.下载 Visual Studio Code https://code.visualstudio.com/ 二.安装 选择想要安装的位置: 后面的点击下一步即可。 三.下载编译器MinGW vscode只是写代码的工具,使用编译器才能编译写的C/C程序,将它转为可执行文件。 MinGW下载链接:…

构造回文数组

目录 原题描述: 题目描述 时间:1s 空间:256M 题目描述: 输入格式: 输出格式: 样例1输入: 样例1输出: 样例2输入: 样例2输出: 约定: 作…

【INTEL(ALTERA)】为什么在编译 HDMI 英特尔® FPGA IP设计示例 VHDL 变体时看到错误 (13879)?

说明 由于英特尔 Quartus Prime Pro Edition 软件版本 23.2 存在一个问题,您在编译 HDMI 英特尔 FPGA IP设计示例的 VHDL 变体时可能会看到以下错误: 错误 (13879): VHDL 绑定指示 hdmi_rx_ram_1port_intel_mce_2010…

微信小程序的图片色彩分析,窃取网络图片的主色调

1、安装 Mini App Color Thief 包 包括下载包,简单使用都有,之前写了,这里就不写了 网址:微信小程序的图片色彩分析,窃取主色调,调色板-CSDN博客 2、 问题和解决方案 问题:由于我们的窃取图片的…