深入理解Java虚拟机(一)JAVA内存区域与内存管理

1. JAVA内存区域与内存管理
img

JVM 内存分哪几个区,每个区的作用是什么?

运行时数据区:

  • 程序计数器

    • 当前线程所执行字节码的行号指示器;
    • 空间线程私有,各线程有自己独立的程序计数器,互不干扰;
    • 执行Java方法时,计数器记录正在执行的字节码地址,执行本地方法时,计数器值为空(Undefined),该区域不存在OOM。
  • Java虚拟机栈

    • 栈帧存储局部变量(基本数据类型、引用类型和returnAdderss类型【指向一条字节码指令的地址】)、操作数栈、动态链接、方法出口信息;

    • 空间线程私有,各线程有自己独立的栈帧,每个线程栈的大小 -Xss 设置;

    • 线程请求的栈深度大于虚拟机所允许的深度:SOE(StackOverFlow Exception);

      虚拟机栈动态扩展时无法申请到足够的内存:OOM(OutOfMemoryError)。

  • 本地方法栈

    • 为虚拟机存储的Native方法服务。线程私有,(OOM,SOE也都存在)。
  • Java堆

    • 存放对象实例,大小(-Xms,-Xmx)设置,OOM,线程共享
  • 方法区

    • 已被虚拟机加载的类信息、常量、静态变量

    • 运行时常量池:(方法区的一部分)

      • Byte,Short,Integer,Long,Character,Boolean种包装类默认创建了数值[-128,127]的相应类型的缓存数据,但是超出此范围仍然会去创建新的对象。

      • String类型通过new创建会分配在堆中,通过“ ”创建分配在常量池中;

        由只包含“ ”创建的String和+组成的String会被存放在常量池中;

        String的intern()方法会查找常量池中是否存在一份equal相等的字符串,如果有则返回引用,如果没有则将自己添加如常量池

        String s1 = new String("xyz"); //创建了几个对象?
        

        "xyz"在类加载时已经创建于常量池,运行时将常量池的对象复制一份到堆中,引用交给s1持有。

  • 直接内存(堆外内存)

    • 使用Native函数库直接使用本机内存,不受JVM限制,但也会存在OOM
发布了54 篇原创文章 · 获赞 11 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/dong_W_/article/details/104698637
今日推荐