JVM入门之内存结构(堆、方法区)

JVM入门之内存结构(堆、方法区)

JVM是Java虚拟机的缩写,是Java技术的核心和基础。学习JVM内存结构对于Java程序员来说非常重要,本文将对JVM内存结构、堆和方法区进行详细讲解。

JVM内存结构

JVM的内存结构主要由以下几个部分组成:

  • 程序计数器
  • 虚拟机栈
  • 本地方法栈
  • 方法区

其中堆和方法区是Java程序中数据存储的主要区域,我们重点来详细介绍。

堆是Java虚拟机中内存最大的一块,所有类的实例和数组都在堆上分配空间。堆是线程共享的,所有线程都可以访问并修改堆中的对象。

Java中,堆内存的大小是通过-Xmx和-Xms指定的,-Xmx指定堆内存的最大容量,-Xms指定堆内存的初始容量。

堆的分类

Java堆分为新生代和老年代两部分,新生代又分为Eden空间、Survivor1空间、Survivor2空间(也叫From空间和To空间)。

  • 新生代:是所有新创建对象的存储空间,占堆空间的一部分,一般为1/3。新生代的大小可以通过-Xmn来指定,默认为整个堆的1/3。

  • 老年代:是存储长期存活的对象的空间,占堆空间的2/3。老年代的大小可以通过-XX:PermSize和-XX:MaxPermSize来指定。

堆的垃圾回收

Java中的垃圾回收主要是针对堆中的对象的回收。垃圾回收的目的是为了使Java程序能够自动释放不再被使用的内存空间。

Java的垃圾回收算法主要包括三种:

  • 标记-清除算法
  • 复制算法
  • 标记-整理算法

其中复制算法一般用于新生代内存的垃圾回收,而标记-清除算法和标记-整理算法一般用于老年代内存的垃圾回收。

方法区

方法区是用于存储类的相关信息,比如类的成员变量、方法信息、静态变量、运行时常量池等等。方法区的大小由-XX:PermSize和-XX:MaxPermSize参数指定,默认值为64M。

方法区的分类

方法区分为两个部分:常量池和类信息。

  • 常量池:Class文件中的常量池用于存放编译期生成的各种字面量和符号引用。
  • 类信息:存放每个类的结构信息,比如成员变量、方法等信息。

方法区的垃圾回收

方法区的垃圾回收主要针对无用的类和常量的回收。Java7及之前的版本中,方法区的垃圾回收主要依靠对类的卸载实现。Java8开始,方法区的垃圾回收采用了元空间的概念进行实现。元空间直接使用本地内存,因此不存在垃圾回收问题。

示例说明

示例一

public class Demo1 {
    public static void main(String[] args) {
        byte[] b1 = new byte[1024 * 1024];
        System.out.println("分配了1M空间给b1");
        byte[] b2 = new byte[1024 * 1024 * 2];
        System.out.println("分配了2M空间给b2");
        byte[] b3 = new byte[1024 * 1024 * 3];
        System.out.println("分配了3M空间给b3");
        byte[] b4 = new byte[1024 * 1024 * 4];
        System.out.println("分配了4M空间给b4");
    }
}

这个示例中分别分配了1M、2M、3M、4M的空间给b1、b2、b3、b4。由于堆大小为5M(默认为整个堆的1/3),因此最后一次分配空间的时候会出现OutOfMemoryError错误。

示例二

public class Demo2 {
    public static void main(String[] args) {
        String s1 = new String("abc");
        String s2 = "abc";
        String s3 = "ab" + "c";
        System.out.println(s1 == s2); // false
        System.out.println(s1 == s3); // false
        System.out.println(s2 == s3); // true
    }
}

这个示例中,我们分别使用new关键字和直接赋值的方式创建了三个字符串对象s1、s2、s3。Java的字符串常量会被JVM缓存,因此s2和s3引用的是同一个字符串常量对象。而s1由于使用了new关键字创建,因此它引用的是一个新的字符串对象,与s2和s3不同。因此s1、s2、s3三个变量的比较结果也是不同的。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:JVM入门之内存结构(堆、方法区) - Python技术站

(0)
上一篇 2023年5月26日
下一篇 2023年5月26日

相关文章

  • Java实现办公文档在线预览功能

    实现Java办公文档的在线预览功能需要完成以下步骤: 步骤一:选择合适的文件预览解决方案 Java实现办公文档在线预览功能需要使用第三方工具来解析文档文件,目前比较流行的解决方案有如下几种: LibreOffice:可实现对多种文档格式的解析,包括Microsoft Office文件,OpenOffice文件,PDF文件等等。 Aspose.Words:仅支…

    Java 2023年5月19日
    00
  • IntelliJ IDEA 中必有得插件和配置

    让我来详细讲解一下“IntelliJ IDEA 中必有得插件和配置”的攻略。 为了让开发者能够更加高效地编写代码,IntelliJ IDEA 提供了丰富的插件和配置选项。以下是一些必备的插件和配置: 一、必备插件 1.1 Lombok Lombok 是一款能够帮助开发者消除 Java 代码中冗余、繁琐的语法的插件。它能够自动生成 getter、setter、…

    Java 2023年5月20日
    00
  • java事务的概念浅析

    接下来我将详细讲解“Java事务的概念浅析”的完整攻略。 Java事务的概念浅析 什么是事务 在计算机领域,事务是指一组对系统中数据的访问和更新操作,这组操作要么全都执行成功,要么全都不执行,保证了数据的一致性。事务是一种能够保证数据在一些列操作中的完整性和一致性的数据处理方式。 事务的ACID属性 在数据库中,事务必须同时具备ACID四个属性: 原子性(A…

    Java 2023年5月20日
    00
  • SpringBoot连接Hive实现自助取数的示例

    下面是“SpringBoot连接Hive实现自助取数的示例”的完整攻略: 一、准备工作 在开始前我们需要准备以下工具和环境: JDK 1.8及以上版本; Maven; IntelliJ IDEA; Hive。 其中,Hive是我们连接数据源的关键。如果你还没有安装Hive,可以参考以下链接进行安装: Hive官网:http://hive.apache.org…

    Java 2023年5月20日
    00
  • 教你用Java SpringBoot如何解决跨域

    教你用 Java Spring Boot 如何解决跨域 在本文中,我们将详细讲解如何使用 Java Spring Boot 解决跨域问题。我们将使用 Spring Boot 2.5.0 版本的源码进行分析。 什么是跨域? 跨域是指在浏览器中,当一个 Web 应用程序试图访问另一个域名下的资源时,浏览器会阻止这种行为。这是由于浏览器的同源策略所导致的。同源策略…

    Java 2023年5月15日
    00
  • java连接Mysql数据库的工具类

    当我们使用Java语言编写程序操作MySQL数据库时,需要用到连接MySQL数据库的相关工具类。下面,我将详细讲解Java连接MySQL数据库的工具类的完整攻略。 1. 引入相关依赖 我们需要在项目中引入MySQL的Java Connector依赖,可以使用以下Maven依赖: <dependency> <groupId>mysql&…

    Java 2023年5月19日
    00
  • Spring Data JPA系列JpaSpecificationExecutor用法详解

    Spring Data JPA系列JpaSpecificationExecutor用法详解 JpaSpecificationExecutor介绍 JpaSpecificationExecutor是Spring Data JPA提供的一个接口,可以用于对JPA规范中Criteria Query查询标准的扩展,使得我们可以根据不同的查询条件,动态生成不同的查询语…

    Java 2023年5月20日
    00
  • SpringBoot集成JmsTemplate(队列模式和主题模式)及xml和JavaConfig配置详解

    一、概述 本文将详细介绍如何在SpringBoot应用程序中使用JmsTemplate集成队列模式和主题模式。本文将提供XML和JavaConfig两种配置方式。我们将从简单的应用程序开始,使用单个生产者和单个队列或主题。然后,我们将更改为多个生产者和多个队列和主题。通过本文,您将了解如何在SpringBoot应用程序中集成消息传递,以便实现单个或分布式系统…

    Java 2023年5月19日
    00
合作推广
合作推广
分享本页
返回顶部