Java面试题冲刺第二十七天–JVM2

yizhihongxing

Java面试题冲刺第二十七天--JVM2

1. 内存模型

Java内存模型主要分为两种:

  • 堆内存:存放我们new出来的对象以及数组等,这部分内存可以动态申请或释放。一般情况下,堆内存比较大。
  • 栈内存:存放基本类型的变量以及对象的引用变量(指针),这些变量会随着程序的运行而申请或释放。栈的空间比较小,一般情况下,栈的大小是在程序启动的时候就固定下来。

2. JVM内存模型

JVM内存模型主要分为五种:

  • 方法区(JDK7及以前称为永久代):存放静态变量、类信息等,这部分内存可以动态申请或释放。运行时类的情况是在方法区中存储。
  • 堆内存:同上。
  • 虚拟机栈:与线程相关的数据存储在虚拟机栈中,包括方法调用的局部变量、返回值等数据。这个是栈内存的一部分。
  • 本地方法栈:较少使用,主要是为了支持本地(native)方法。
  • PC寄存器:记录当前线程执行的代码行号,也就是JVM中的“程序计数器”。

3. GC算法

  • 新生代GC:一般采用复制算法。
  • 老年代GC:一般采用标记-清除算法。

在JDK 1.2之后,Java默认使用的是能够自动适应应用程序所需的并行垃圾收集器(Parallel Collector)——也称之为吞吐量优先收集器(The throughput collector)。

4. 分代收集

对于JVM的“分代收集”策略,一般分为以下几步:

  • 对于新生代开辟一段内存,称之为“Eden”空间;
  • 运行过程中,将对象放入Eden空间;
  • 当Eden空间满时,将其中存活的对象,复制到其他内存空间,称之为“Survivor”空间中;
  • 当“Survivor”空间也满时,将存活下来的对象放入老年代空间;
  • 老年代也满,就会触发Full GC,也就是对整个堆都进行清理。

5. 示例说明

示例1

public class Test {
    private static int count = 0;
    public static void main(String[] args) {
        checkMemory();
    }
    private static void checkMemory(){
        while (true){
            new Thread(() -> {
                byte[] array = new byte[1024 * 1024];
                try {
                    Thread.sleep(1000);
                    count++;
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }).start();
            System.out.println("count=" + count);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

这段代码实现了不断开启新的线程进行内存分配操作。在输出中,你会看到类似如下的内容:

count=985
count=987
count=999
Exception in thread "Thread-2" java.lang.OutOfMemoryError: Java heap space

这是因为每当开启一个新线程时,都会在堆内存中占用一定空间。由于没有使用相关手段对线程进行回收,最终导致堆内存耗尽。

示例2

public class Test {
    private static int count = 0;
    public static void main(String[] args) {
        while (true){
            new Thread(() -> {
                byte[] array = new byte[1024 * 1024];
                try {
                    Thread.sleep(1000);
                    count++;
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }).start();
            System.out.println("count=" + count);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

这段代码与示例1非常相似,唯一的区别就是while循环在main方法中而不是checkMemory方法中。在输出中,你会看到类似如下的内容:

count=390
count=411
count=422
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space

这是因为main方法一直处于运行状态,并在其中使用while循环不断加入新线程,最终导致堆内存耗尽。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java面试题冲刺第二十七天–JVM2 - Python技术站

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

相关文章

  • 使用SpringMVC在redirect重定向的时候携带参数的问题

    使用SpringMVC在redirect重定向的时候携带参数是一件常见的需求,本文将为您详细讲解如何解决这个问题。 解决方案 在SpringMVC中,可以使用RedirectAttributes实现在重定向时携带参数,具体的步骤如下: 在Controller方法中添加一个RedirectAttributes参数: java @RequestMapping(v…

    Java 2023年6月15日
    00
  • 详解SpringBoot实现JPA的save方法不更新null属性

    下面我将详细讲解如何实现SpringBoot的JPA的save方法不更新null属性的方法: 问题描述 使用SpringBoot中JPA进行开发时,对于已经存在的实体对象进行更新操作时,如果实体对象中有一些属性值为null,那么在执行save()方法时,JPA会自动将这些属性更新为null,但是我们有时候并不希望这样,我们希望保留原来已经存在的值,仅仅修改非…

    Java 2023年5月20日
    00
  • springboot 2.3之后消失的hibernate-validator解决方法

    下面是详细的攻略: 问题背景 在Spring Boot 2.3版本之后,引入了一个新的starter库,名为validation-starter,用于提供Java Bean的数据校验功能。同时,hibernate-validator也被移出了Spring Boot的核心依赖,这导致运行时找不到这个库,会报出ClassNotFoundException的错误。…

    Java 2023年5月20日
    00
  • Maven分模块开发执行指令失败的问题

    Maven分模块开发是一种常见的软件开发方法,但在进行模块执行指令时,有时会遇到执行失败的问题。本攻略旨在帮助开发人员解决Maven分模块开发执行指令失败的问题,步骤如下: 一、检查pom.xml文件配置 在进行Maven分模块开发时,每个子模块都有自己的pom.xml文件。执行指令失败时,首先需要检查各个子模块的pom.xml文件是否正确配置。特别要注意以…

    Java 2023年5月19日
    00
  • Java中的Spring Security配置过滤器

    我来详细讲解Java中的Spring Security配置过滤器的完整攻略。 首先,需要明确的是,Spring Security 是 Spring 框架中用于进行身份认证和授权的模块。Spring Security 的核心是一组过滤器链,这组过滤器链负责 Web 请求的拦截和过滤,来确保每个请求都能够按照应用程序的安全策略进行处理。 在 Spring Sec…

    Java 2023年5月20日
    00
  • 在JSP中处理虚拟路径

    如何在JSP中处理虚拟路径 在JSP中处理虚拟路径需要使用到JSP内置对象中的application对象、pageContext对象和HttpServletRequest对象。通过这些内置对象中提供的方法来获取虚拟路径的实际路径,并将其与页面的文件路径拼接在一起。 具体实现过程如下: 1.获取虚拟路径的实际路径 在JSP页面中获取虚拟路径的实际路径可以通过以…

    Java 2023年6月15日
    00
  • Servlet3.0新特性全解

    Servlet 3.0 新特性全解 Servlet 3.0 是 Java Servlet API 的最新版本,它带来了许多新特性和改进,其中一些特性可以让开发人员更加方便地开发 Web 应用程序。 1. Web Fragments(Web 片段) Web Fragments 是一项 Servlet 3.0 中最有用的新特性之一。Web Fragments 允…

    Java 2023年6月15日
    00
  • Idea开发工具之SpringBoot整合JSP的过程

    接下来我会详细讲解在Idea开发工具中如何整合SpringBoot和JSP。 准备工作 在开始之前,确保你已经完成以下准备工作: 安装了JDK和Idea开发工具。 创建一个SpringBoot项目。 确保pom.xml中已经添加了对于Spring Web和Tomcat的依赖。 整合JSP 第一步:在pom.xml中添加依赖 在pom.xml中添加以下依赖: …

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