JVM对象的创建流程与内存分配

创建流程

加载
验证
解析
准备
初始化
使用
写在

对象内存分配方式

内存分配的方法有两种:不同垃圾收集器不一样

  • 指针碰撞(Bump the Pointer)
  • 空闲列表(Free List)
    在这里插入图片描述
    指针碰撞示意图:
    在这里插入图片描述

内存分配安全问题

在分配内存的时候,虚拟机给A线程分配内存过程中,指针未修改。此时B线程同时使用了同样一块内存。是不是就出现了线程的安全性问题?
在JVM中有两种解决办法:

  1. CAS 是乐观锁的一种实现方式。虚拟机采用 CAS 配上失败重试的方式保证更新操作的原子性。
  2. TLAB本地线程分配缓冲(Thread Local Allocation Buffer即TLAB):为每一个线程预先分配一块内存

JVM在第一次给线程中的对象分配内存时,首先使用CAS进行TLAB的分配。当对象大于TLAB中的剩余内存或TLAB的内存已用尽时,再采用上述的CAS进行内存分配。

对象内存分配流程【重要】:

在这里插入图片描述

对象怎样才会进入老年代?重点

对象内存分配:

  • 新生代:新对象大多数都默认进入新生代的Eden区
  • 进入老年代的条件:四种情况
    在这里插入图片描述
    在这里插入图片描述
    老年代的担保示意图:
    在这里插入图片描述

小结

  1. 当Eden区存储不下新分配的对象时,会触发minorGC
  2. GC之后,还存活的对象,按照正常逻辑,需要存入到Survivor区。
  3. 当无法存入到幸存区时,此时会触发担保机制
  4. 发生内存担保时,需要将Eden区GC之后还存活的对象放入老年代。后来的新对象或者数组放入Eden区。

案例演示:对象分配过程

大对象直接进入老年代

package com.hero.jvm.object;
/**
* 测试:大对象直接进入到老年代
* -Xmx60m -Xms60m -XX:NewRatio=2 -XX:SurvivorRatio=8 -XX:+PrintGCDetails * -XX:PretenureSizeThreshold
*
*/
public class YoungOldArea {
   
    public static void main(String[] args) {
   
        byte[] buffer = new byte[1024*1024*20]; //20M
    }
}
-XX:NewRatio=2 新生代与老年代比值
-XX:SurvivorRatio=8 新生代中,Eden与两个Survivor区域比值 
-XX:+PrintGCDetails 打印详细GC日志
-XX:PretenureSizeThreshold 对象超过多大直接在老年代分配,默认值为0,不限制

在这里插入图片描述

02-对象内存分配的过程:

/*
-Xmx600m -Xms600m -XX:+PrintGCDetails
*/
public class HeapInstance {
   
    public static void main(String[] args) {
   
        List<Picture> list = new ArrayList<>();
        while (true){
   
} }
    try {
   
        Thread.sleep(20);
    } catch (InterruptedException e) {
   
        e.printStackTrace();
}
    list.add(new Picture(new Random().nextInt(1024 * 1024)));
}
class Picture{
   
    private byte[] pixels;
    public Picture(int length){
   
        this.pixels = new byte[length];
    }
}

在这里插入图片描述

相关推荐

  1. JVM对象创建内存分配机制分析

    2024-02-22 03:00:02       40 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-02-22 03:00:02       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-02-22 03:00:02       100 阅读
  3. 在Django里面运行非项目文件

    2024-02-22 03:00:02       82 阅读
  4. Python语言-面向对象

    2024-02-22 03:00:02       91 阅读

热门阅读

  1. C++面试高频问题汇总( 一)

    2024-02-22 03:00:02       56 阅读
  2. gtowizard合租cash和锦标赛mtt

    2024-02-22 03:00:02       46 阅读
  3. 前端常见面试题

    2024-02-22 03:00:02       52 阅读
  4. Qt 基本知识

    2024-02-22 03:00:02       47 阅读
  5. webrtc 中 FIR PLI 有何区别? 分别适用于什么场景

    2024-02-22 03:00:02       48 阅读
  6. vue 学习definproperty方法

    2024-02-22 03:00:02       61 阅读
  7. Gradio学习(二)—————学习block布局

    2024-02-22 03:00:02       50 阅读
  8. SpringBoot-将Bean放入容器的五种方式

    2024-02-22 03:00:02       49 阅读
  9. Sora 使用教程,新手小白可用

    2024-02-22 03:00:02       61 阅读
  10. win32 汇编调用C标准库函数

    2024-02-22 03:00:02       52 阅读
  11. SpringBoot+WebSocket实现即时通讯(一)

    2024-02-22 03:00:02       47 阅读
  12. 触发器的类型有哪些?

    2024-02-22 03:00:02       43 阅读
  13. 使用 Spring Authorization Server

    2024-02-22 03:00:02       51 阅读
  14. 计算机软件学习大方向

    2024-02-22 03:00:02       49 阅读
  15. 19 OpenGL计算着色器

    2024-02-22 03:00:02       45 阅读