广告
返回顶部
首页 > 资讯 > 前端开发 > JavaScript >详解JVM系列之内存模型
  • 488
分享到

详解JVM系列之内存模型

2024-04-02 19:04:59 488人浏览 独家记忆
摘要

目录1. 内存模型和运行时数据区2、思维导图和图例3、对象向JVM申请空间4、为什么需要Survivor区?5、为什么需要两个Survivor区?6、例子进行验证堆内

1. 内存模型和运行时数据区

这一章学习java虚拟机内存模型(Java Virtual Machine menory model),可以这样理解,jvm运行时数据库是一种规范,而JVM内存模型是对改规范的实现

java虚拟机重点存储数据的是堆和方法区,所以本章节也重点从这两个方面进行比较详细描述。堆和方法区是内存共享的,而java虚拟机栈、Native方法栈、程序计数器是线程私有的

2、思维导图和图例

一个是非堆区(方法区),方法区也一般被称之为“永久代”。另外一个是堆区,分为young区和old区,young区又分为两个部分,一个是Eden区,一个是Survivor区(S0+S1),S0区也可以称之From区,S1也可以称之为To区

3、对象向JVM申请空间

4、为什么需要Survivor区?

为什么需要Survivor区?只有Eden不行吗?

假设不设计出Survivor区,Eden区进行一次MinorGC,对象就直接被送到Old区,这样一来Old区很快就被填满,Old区一满,就会进行FullGC(Old区会进行MajorGC,一般伴随着MinorGC),FullGC是很耗时的,所以设计出Survivor区的目的是减少对象被送到Old区,有一个过渡的Survivor区

补充:Minor GC:新生代
Major GC:老年代
Full GC:新生代+老年代
Eden:S1:S2是8:1:1

5、为什么需要两个Survivor区?

需要两个Survivor区的目的是为了避免内存碎片化。为什么这么说?
假设只设计出一个Survivor区,一旦Eden区满了,就会进行Minor GC,Eden区存活的对象就会被移动到Survivor区,等下一次Eden区满时候,问题就来了,进行MinorGC就将Eden区对象硬放到Survivor区,这样就导致了对象所占的内存是不连续的

6、例子进行验证

堆内存溢出


import lombok.Data;
import org.springframework.WEB.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;

@RestController
public class HeapController {

    List<Foo> list = new ArrayList<Foo>();
    @GetMapping(value = {"heap"})
    public String heapTest() {
        while (true) {
            list.add(new Foo());
        }
    }


    @Data
    class Foo {
        String str;
    }
}

访问接口,出现内存溢出;

java.lang.OutOfMemoryError: Java heap space

...

可以设置参数:比如-Xms64M -Xmx512M

方法区内存溢出

使用asm,Maven配置:


<dependency>
  <groupId>asm</groupId>
  <artifactId>asm</artifactId>
  <version>3.3.1</version>
</dependency>

编写代码,向方法区中添加Class的信息,注意,电脑性能不够好,不要执行此代码,很容易,造成电脑重启,太吃内存,也可以调小循环次数


import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;

import java.util.ArrayList;
import java.util.List;

public class MyMetaspace extends ClassLoader {

  public static List<Class<?>> createClasses() {
    List<Class<?>> classes = new ArrayList<Class<?>>();
    for (int i = 0; i < 10000000; ++i) {
      ClassWriter cw = new ClassWriter(0);
      cw.visit(Opcodes.V1_1, Opcodes.ACC_PUBLIC, "Class" + i, null,
              "java/lang/Object", null);
      MethodVisitor mw = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>",
              "()V", null, null);
      mw.visitVarInsn(Opcodes.ALOAD, 0);
      mw.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object",
              "<init>", "()V");
      mw.visitInsn(Opcodes.RETURN);
      mw.visitMaxs(1, 1);
      mw.visitEnd();
      MyMetaspace test = new MyMetaspace();
      byte[] code = cw.toByteArray();
      Class<?> exampleClass = test.defineClass("Class" + i, code, 0,
              code.length);
      classes.add(exampleClass);
    }
    return classes;
  }
}

方法区测试接口:


import com.example.jvm.jvmexceptionexample.asm.MyMetaspace;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;

@RestController
public class NonHeapController {

    List<Class<?>> list = new ArrayList<Class<?>>();

    @GetMapping(value = {"/noheap"})
    public String noheap() {
        while (true) {
            list.addAll(MyMetaspace.createClasses());
        }
    }

}

java.lang.OutOfMemoryError: Metaspace

at java.lang.ClassLoader.defineClass1(Native Method) ~[na:1.8.5_54]

处理方法,设置Metaspace的大小,比如-XX:MetaspaceSize=64M -XX:MaxMetaspaceSize=512M

Java虚拟机栈

在前面学习,java虚拟机栈是通过栈帧方式存储,一个方法对应一个栈帧,按照队列模式进栈,所以要测试程序导致java虚拟机栈出现问题,可以通过递归方法方式进行测试:


import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class StackController {

    public static long count = 0;

    public static void add(long i) {
        count ++ ;
        add(i);
    }

    @GetMapping(value = {"stack"})
    public void stack() {
        add(1);
    }

}

StackOverflow,栈溢出异常:

java.lang.StackOverflowError: null

at com.example.jvm.jvmexceptionexample.controller.StackController.add(StackController.java:14) ~[classes/:na]

处理方法,设置-Xss256k:设置每个线程的堆栈大小。jdk 5以后每个线程堆栈大小为1M,以前每个线程堆栈大小为256K

以上就是详解JVM系列之内存模型的详细内容,更多关于JVM 内存模型 内存结构的资料请关注编程网其它相关文章!

--结束END--

本文标题: 详解JVM系列之内存模型

本文链接: https://www.lsjlt.com/news/127978.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 详解JVM系列之内存模型
    目录1. 内存模型和运行时数据区2、思维导图和图例3、对象向JVM申请空间4、为什么需要Survivor区?5、为什么需要两个Survivor区?6、例子进行验证堆内...
    99+
    2022-11-12
  • 【JVM】JVM内存模型详解
    一、JVM是什么? JVM是Java Virtual Machine(Java虚拟机)的缩写,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。由一套字节码指令集、一组寄存器、一个栈、一个垃圾回收...
    99+
    2023-09-16
    jvm java 面试
  • JVM系列之内存模型的示例分析
    这篇文章主要介绍JVM系列之内存模型的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!1. 内存模型和运行时数据区这一章学习java虚拟机内存模型(Java Virtual machine menory mod...
    99+
    2023-06-15
  • 【JVM】JVM内存模型(详细)
    目录 一.JVM概述1.jvm简介2.jvm作用3.jvm的内存模型 二.类加载器1.类加载器的作用2.加载器的类型3.双亲委派机制的运行过程4.双亲委派机制优缺点5.为什么要破坏双亲委派机制6.破坏双亲委派机制的方式 三....
    99+
    2023-08-16
    jvm java 面试
  • JVM入门之JVM内存结构内容详解
    一、java代码编译执行过程 源码编译:通过Java源码编译器将Java代码编译成JVM字节码(.class文件) 类加载:通过ClassLoader及其子类来完成...
    99+
    2022-11-12
  • JVM(Java虚拟机)详解(JVM 内存模型、堆、GC、直接内存、性能调优)
    JVM(Java虚拟机) JVM 内存模型 结构图 jdk1.8 结构图(极简) jdk1.8 结构图(简单) JVM(Java虚拟机): 是一个抽象的计算模型。如同一台真实的机器,它有自己的指令集和执行引擎,可以在运行时操控内存区域。...
    99+
    2023-08-30
    jvm GC 直接内存 jvm性能调优
  • Java内存模型之happens-before概念详解
    简介 happens-before是JMM的核心概念。理解happens-before是了解JMM的关键。 1、设计意图 JMM的设计需要考虑两个方面,分别是程序员角度和编译器、处理...
    99+
    2022-11-12
  • Java内存模型详解
    目录什么是JMM主存与工作内存volatile 关键字有什么用一个线程对共享变量做了修改之后,其他的线程能够看到(感知到)该变量的这种修改(变化)什么是JMM JMM全称Java M...
    99+
    2023-05-18
    Java内存模型 Java JMM模型
  • Java——内存模型详解!
    Java内存模型是一种抽象的规则或规范,定义了程序中存在竞争现象的对象(包括实例字段、静态字段和数组对象,不包括局部变量,形式参数;后者是线程私有,不存在竞争问题)的访问方式。         如果我们要想深入了解Java并发编程,就要先理...
    99+
    2023-10-20
    java 开发语言
  • JVM内存管理之JAVA语言的内存管理详解
    引言内存管理一直是JAVA语言自豪与骄傲的资本,它让JAVA程序员基本上可以彻底忽略与内存管理相关的细节,只专注于业务逻辑。不过世界上不存在十全十美的好事,在带来了便利的同时,也因此引入了很多令人抓狂的内存溢出和泄露的问题。可怕的事情还不只...
    99+
    2023-05-31
    jvm 内存管理 java
  • Java内存模型JMM详解
    Java Memory Model简称JMM, 是一系列的Java虚拟机平台对开发者提供的多线程环境下的内存可见性、是否可以重排序等问题的无关具体平台的统一的保证。(可能在术语上与Java运行时内存分布有歧义,后者指堆、方法区、线程栈等内存...
    99+
    2023-05-30
    java 内存模型 详解
  • 详解Java的内存模型
    目录JVM的内存模型Java “一次运行,到处编译” 的真面目JVM的本质和位置JVM的内存模型总览线程私有区域线程共享区域直接内存从例子来理解内存模型JVM的内存模型 Java “...
    99+
    2022-11-12
  • JAVA内存模型(JMM)详解
    目录前言JAVA并发三大特性可见性有序性原子性Java内存模型真面目Happens-Before规则1.程序的顺序性规则2. volatile 变量规则3.传递性锁的规则5.线程 s...
    99+
    2022-12-08
    JAVA 内存模型 java内存模型和jvm内存模型的区别 java jmm模型
  • 一篇文章带你了解JVM内存模型
    目录1. JVM介绍 1.1 什么是JVM?1.2 JVM的优点 1.2.1 一次编写,到处运行。1.2.2 自动内存管理,垃圾回收机制。1.2.3 数组下标越界...
    99+
    2022-11-12
  • Java内存区域与内存模型详解
    这篇文章主要介绍“Java内存区域与内存模型详解”,在日常操作中,相信很多人在Java内存区域与内存模型详解问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java内存区域与内存模型详解”的疑惑有所帮助!接下来...
    99+
    2023-06-02
  • Java内存模型中的happen-before关系详解
    目录前言概述为什么需要 JMM,它试图解决什么问题?JMM 是怎么解决可见性等问题的呢?后记前言 Java 语言在设计之初就引入了线程的概念,以充分利用现代处理器的计算能力,这既带来...
    99+
    2022-11-13
    Java happen before Java 内存模型
  • Java内存模型图文详解
    1. 概述多任务和高并发是衡量一台计算机处理器的能力重要指标之一。一般衡量一个服务器性能的高低好坏,使用每秒事务处理数(Transactions Per Second,TPS)这个指标比较能说明问题,它代表着一秒内服务器平均能响应的请求数,...
    99+
    2014-08-03
    Java
  • GoLang内存模型详细讲解
    目录栈内存-协程栈-调用栈逃逸分析go 堆内存堆如何进行分配go 语言对象的垃圾回收如何减少GC对性能的分析GC 优化效率栈内存-协程栈-调用栈 为什么go的栈是在堆上? go 协程...
    99+
    2022-12-15
    GoLang内存模型 Go内存模型
  • 详解JVM系列之对象的锁状态和同步
    目录java对象头java中锁状态的变化偏向锁biased locking轻量级锁thin lock重量级锁三种锁状态的不同java对象头 Java的锁状态其实可以分为三种,分别是偏...
    99+
    2022-11-12
  • 华为技术专家讲解JVM内存模型(收藏)
    目录1 Program Counter Register (程序计数寄存器)1.1. 定义1.2. 作用1.3. 特点2. Java虚拟机栈(JVM Stack)2.1. 定义2.2...
    99+
    2022-11-12
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作