美文网首页
1、自动内存管理:内存划分与内存溢出

1、自动内存管理:内存划分与内存溢出

作者: lois想当大佬 | 来源:发表于2019-12-10 13:07 被阅读0次

    一、内存划分


    image.png

    1、程序计数器
    线程私有,生命周期和线程相同。记录当前线程所执行字节码的行号,为线程切换后能恢复到正确的执行位置。
    该区域没有任何OutOfMenoryError情况。

    2、虚拟机栈
    线程私有,生命周期和线程相同。虚拟机栈描述的是java方法执行的内存模型:方法在执行时会创建一个栈帧用于存储:局部变量表、操作数栈、动态链接、方法出口等信息。方法从调用直至执行完成,对应着一个栈帧在虚拟机栈中入栈到出栈的过程。
    异常情况:
    StackOverflowError:线程请求的栈深度大于虚拟机所允许的深度。
    OutOfMenoryError:动态扩展虚拟机栈,但扩展时无法申请到足够的内存。

    3、本地方法栈
    线程私有,生命周期和线程相同。不同于虚拟机栈执行java方法【字节码】,本地方法栈执行native方法。发挥作用与虚拟机栈类似。异常情况同虚拟机栈。

    4、堆
    线程共享,虚拟机启动时创建。存放对象实例和数组。
    异常情况:
    OutOfMenoryError:无法完成实例分配,并且堆无法扩展。

    5、方法区
    线程共享,虚拟机启动时创建。存放类信息、常量、静态变量、代码数据。
    OutOfMenoryError:无法满足内存分配需求。

    6、运行时常量池
    方法区的一部分。存放编译期生成的各种字面量和符号引用。
    OutOfMenoryError:无法满足内存分配需求。

    7、直接内存
    不属于运行时数据区的一部分。使用native函数库直接分配堆外内存,然后通过一个存储在java堆中的DirectByteBuffer对象作为这块内存的引用进行操作。
    OutOfMenoryError:无法满足内存分配需求。

    二、对象创建、布局、访问
    1、对象创建
    虚拟机遇到new指令,检查常量池是否包含该类的符号引用,该类是否被加载,若没有则加载该类。
    根据堆内存是否规整有两种内存分配方式:
    指针碰撞:堆规整。用过的内存在一边,空闲内存在另一边,中间放着一个指针作为分界点的指示器,分配内存则把指针向空闲那边挪动一段与对象大小相等的距离。
    空闲列表:堆不规整。虚拟机维护一个列表,记录哪些内存可用,在分配时找到一块足够大的空间划分给对象实例,并更新列表记录。
    堆内存分配线程安全策略:
    CAS失败重试。
    线程缓冲区TLAB:为每个线程预先分配一小块内存,只有TLAB用完并分配新的TLAB时才需要同步锁定。

    2、对象布局
    对象布局有3块区域:
    对象头:
    1、存储对象自身运行时数据:哈希码、GC分代年龄、锁状态等。
    2、类型指针,即对象指向它的类元数据的指针,通过该指针确定该对象属于哪个类。
    实例数据:对象字段内容
    对其填充:对象大小必须是8的整数倍,不够则进行对其填充。

    1、对象访问
    对象访问的两种方式:
    句柄:稳定。对象移动只需改变句柄中的实例数据指针,而reference本身无须改变。


    image.png

    直接指针:速度快。节省一次指针开销。Sun HotSpot默认使用直接指针进行对象访问。


    image.png

    三、内存溢出
    1、堆溢出
    -Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError
    将堆最小值Xms和最大值Xmx设置为一样即可避免自动扩展,通过参数HeapDumpOnOutOfMemoryErrorr让虚拟机在出现内存溢出异常时Dump出当前的内存堆转储快照以便事后进行分析。


    虚拟机启动参数 堆内存溢出代码

    2、虚拟机栈与本地方法栈溢出
    通过参数-Xss144k缩减栈容量,测试StackOverFlowError异常。


    虚拟机参数 线程请求栈深度超过虚拟机允许的深度

    3、方法区溢出
    由于方法区jvm参数-XX:PermSize -XX:MaxPermSize在jdk8已经被移除,该溢出待补充。


    image.png

    4、直接内存溢出
    由于本人使用的jdk13不包含程序包sun.misc,本异常待补充。


    image.png
    image.png

    检查-XX:MaxDirectMenorySize,如果该参数没配置,则默认使用-Xmx。

    下一篇:2、垃圾回收与内存分配

    相关文章

      网友评论

          本文标题:1、自动内存管理:内存划分与内存溢出

          本文链接:https://www.haomeiwen.com/subject/alxggctx.html