• jvm内存模型和垃圾回收


    堆与栈分开设计是为什么呢?

    • 栈存储了处理逻辑、堆存储了具体的数据,这样隔离设计更为清晰
    • 堆与栈分离,使得堆可以被多个栈共享。
    • 栈保存了上下文的信息,因此只能向上增长;而堆是动态分配

    栈的大小可以通过-XSs设置,如果不足的话,会引起java.lang.StackOverflowError的异常

    栈区

    线程私有,生命周期与线程相同。每个方法执行的时候都会创建一个栈帧(stack frame)用于存放 局部变量表、操作栈、动态链接、方法出口。

    存放对象实例,所有的对象的内存都在这里分配。垃圾回收主要就是作用于这里的。

    • 堆得内存由-Xms指定,默认是物理内存的1/64;最大的内存由-Xmx指定,默认是物理内存的1/4。
    • 默认空余的堆内存小于40%时,就会增大,直到-Xmx设置的内存。具体的比例可以由-XX:MinHeapFreeRatio指定
    • 空余的内存大于70%时,就会减少内存,直到-Xms设置的大小。具体由-XX:MaxHeapFreeRatio指定。

    因此一般都建议把这两个参数设置成一样大,可以避免JVM在不断调整大小。

    程序计数器

    这里记录了线程执行的字节码的行号,在分支、循环、跳转、异常、线程恢复等都依赖这个计数器。

    方法区

    类型信息、字段信息、方法信息、其他信息

    总结

    名称特征作用配置异常
    栈区 线程私有,使用一段连续的内存空间 存放局部变量表、操作栈、动态链接、方法出口 -XSs StackOverflowError OutOfMemoryError
    线程共享,生命周期与虚拟机相同 保存对象实例 -Xms -Xmx -Xmn OutOfMemoryError
    程序计数器 线程私有、占用内存小 字节码行号
    方法区 线程共享 存储类加载信息、常量、静态变量等 -XX:PermSize -XX:MaxPermSize OutOfMemoryError

    上面可以看到堆分成三个区域:

    • 新生代(Young Generation):用于存放新创建的对象,采用复制回收方法,如果在s0和s1之间复制一定次数后,转移到年老代中。这里的垃圾回收叫做minor GC;
    • 年老代(Old Generation):这些对象垃圾回收的频率较低,采用的标记整理方法,这里的垃圾回收叫做 major GC。
    • 永久代(Permanent Generation):存放Java本身的一些数据,当类不再使用时,也会被回收。

    这里可以详细的说一下新生代复制回收的算法流程:

    在新生代中,分为三个区:Eden, from survivor, to survior。

    • 当触发minor GC时,会先把Eden中存活的对象复制到to Survivor中;
    • 然后再看from survivor,如果次数达到年老代的标准,就复制到年老代中;如果没有达到则复制到to survivor中,如果to survivor满了,则复制到年老代中。
    • 然后调换from survivor 和 to survivor的名字,保证每次to survivor都是空的等待对象复制到那里的。
  • 相关阅读:
    03_Redis数据类型(List)
    02_Redis数据类型(String、Hash)
    01_Redis基础
    22_AOP_切面——静态切面
    21_AOP_Advice增强2(异常、引介)
    20_AOP_Advice增强1(前置、后置、环绕)
    19_AOP概述
    18_CGLib动态代理
    利用NTP搭建自己的ntp服务
    VM设置BIOS延长时间
  • 原文地址:https://www.cnblogs.com/panxuejun/p/8779634.html
Copyright © 2020-2023  润新知