• JVM系列(三):JVM内存结构和参数说明


    一、概述,内存结构图

    二、堆Heap,存放对象实例,是垃圾回收的主要区域,非堆的内存不进行GC,GC会导致程序运行中断, 物理上可以不连续,堆空间不足时会产生OutOfMemoryException,各个线程的共享区域

    1. 年轻代

    a. Eden空间:存放新生的对象,绝大部分对象在这里;引发minor collection

    b. From Survive空间:存放每次垃圾回收后存活的对象

    c. To Survive空间

    2. 老年代:存放应用程序中生命周期长的存活对象, 引发major collection,即Full gc,会严重影响性能

    3. 参数设置大小

    -Xms 设置堆的最小空间

    -Xmx 设置堆的最大空间

    -XX:NewSize 设置年轻代的最小空间

    -XX:MaxNewSize 设置年轻代的最大空间

    -XX:PermSize 设置永久代的最小空间,在方法区

    -XX:MaxPermSize 设置永久代的最大空间,在方法区

    -Xss 设置线程的栈的空间

    老年代的空间=堆的空间大小-年轻代的空间大小

    三、方法区Method Area

    1. 存储类信息、常量、静态变量等数据,是线程共享的区域,也可以叫永久代

    2. 当空间不够,产生OutOfMemoryException

    四、栈Stack:主要用于方法的执行,是线程私有的区域

    1. 程序计数器

    控制程序流程,分支、跳转等操作

    2. JVM栈和本地方法栈

    方法调用相关,会产生StackOverFlow 

    五、主内存和工作内存

    1. 概念:

    主内存:主要包括本地方法区和堆,所有线程共享

    工作内存:每个线程私有的栈和寄存器(程序计数器和cpu工作的高速缓存区),抽象概念,物理上不存在

    2. 原理:

    a. 所有的变量都存在主内存中,所有线程共享,new对象也放在主内存中

    b. 每个线程都有自己的工作内存,线程对变量的操作是对工作内存中从主内存拷贝过来的变量,而不能对主内存中的变量进行操作

    b. 线程间的变量传递需要通过主内存,而不能直接访问其他线程工作内存中的变量

    六、内存模型与多线程

    1. 多线程的并发问题都会反映在java内存模型上,所谓线程安全就是控制多个线程对某个资源的有序读写

    2. Java内存模型主要解决两个问题:可见性和有序性

    3. volatile解决可见性问题,不保证有序性,适合直接赋值的场景,当一个线程修改了共享变量,其他线程应该看到最新修改的值,被volatile修饰的变量不会被拷贝到工作线程中,在主内存中被修改

    4. synchronized可以解决可见性和有序性,保证共享变量的正确性

    5. 线程消耗CPU:stackoverflow,对象消耗内存: outofmemory

    6. threadlocal: 线程局部变量,即每个线程从主内存中拷贝的变量副本

  • 相关阅读:
    如何从零开始创建一个IT信息系统
    Linux常用命令
    vue.js 3.2.20: 用rem实现移动端和pc的兼容
    vue.js3.2.6:路由处理404报错(vue-router@4.0.11)
    vue.js项目在nginx上部署:使spring后端记录真实ip地址
    vue.js 3.0.5:用vue-i18n开发i18n国际化功能(vue-i18n@9.2.0)
    前台项目基础框架之spring boot后端(spring boot v2.5.4)
    前台项目基础框架之vue前端(vue@3.2.6)
    intellij idea 2021.2:为一个spring boot项目改名
    git:修改项目的remote地址(git version 2.30.2)
  • 原文地址:https://www.cnblogs.com/june0816/p/8011573.html
Copyright © 2020-2023  润新知