• jvm内存模型


    1.内存模式概览:

    2.主要参数设置:

      堆:初始化堆内存-Xms 最大堆内存 -Xmx  新生代:-Xmn 如:Xmx2048M

      元空间:元空间使用的是直接内存,默认大小是21M,超过该值会触发FullGC,同时会扩容,因此为了启动时,更快,需要设置该值:

            - XX:MaxMetaspaceSize 最大元空间,默认-1 代表只跟本地内存大小有关
            -XX:MetaspaceSize 初始化元空间 达到该值会触发FullGC,默认是21M
            由于调整元空间会触发fullGC,那么建议两者大小设置一致,8G内存建议设置为512M

    如:-XX:MetaspaceSize=512M

    线程栈:-Xss128k 代表设置某个线程栈的总大小是128k,默认是1M,值越大,那么该线程能够调用的方法深度越深,值越小,则能创建的线程数越多,下面举个列子:

     在Xss128k的情况下:

     

     将其改成1M再测试:

    面试题:能否对JVM调优,让其几乎不发送FullGC?答案是能的,将年轻代设置大一点就可以了

    3.对象的创建过程

     内存分配:

         1.指针碰撞(默认)如果内存是规整的,已分配的在一边,未分配的在一边,中间有个指针分割,分配时,只要移动指针到对象大小的空间即可

         2.空闲列表: 如果内存是不规整的,此时需要用一个空闲列表来记录哪些内存是可分配的

    并发问题:a对象和b对象同时需要分配一块内存,此时怎么解决

        1.CAS失败重试方式

        2.本地线程分配缓冲区:TLAB:意思是在堆上给每个线程分配一小块内存,该线程创建的对象,优先在该内存中分配,如果内存不足,在使用指针碰撞方式分配

        JVM会默认开启­XX:+UseTLAB,­XX:TLABSize 指定TLAB大小。

    初始化:给变量分配默认值

     设置对象头:(包含:marker work,类型指针,数组长度):

     4.对象指针压缩:

    在64位系统中,java虚拟机使用32位的指针,如果没进行压缩,会导致内存增多,占用较大宽带,同时GC也会承受较大压力,32位地址支持最大堆内存是4G,如果内存大于32GB,压缩指针会失效

    参数控制:­XX:+UseCompressedOops(默认开启),禁止指针压缩:­XX:­-UseCompressedOops,如果只是对对象头的类型指针进行压缩

         ‐XX:+UseCompressedClassPointers 默认开启的压缩对象头里的类型指针Klass Pointer

     5.对象在堆中分配大概流程:

     具体流程描述:

          1. 对象分配时,需要判断对象是否能在栈分配(好处是对象的销毁不用经过GC,方法调用完直接销毁,判断的依据:逃逸分析,简单的说,一个对象只在方法中用到,如:

     如果对象太大,在栈中分配不下,依然会在堆中创建该对象,栈中如果没有连续的空间来分配,那么就需要用到标量替换,啥意思呢,例如User这个对象有Id和name2个属性,我只要在栈中找到内存分别存Id和name属性来代替User对象;

    jdk1.7后是默认开启逃逸分析和标量替换:-XX:+DoEscapeAnalysis(逃逸分析) ‐XX:+EliminateAllocations(标量替换)

    2. 大对象直接分配到老年区,如字符串,数组,那到底啥样的才是大对象,可以同过参数来判断:-XX:PretenureSizeThreshold=1000000 (单位是字节) ,这个参数只在 Serial 和ParNew两个收集器下有效。

    3. 如果TLAB(线程本地分配缓冲)也就是堆中分配给线程的一小块内存地址,如果能放到下该对象,就存起来,如果放不下,就通过指针碰撞方式,在堆中划分内存

    4.如果对象放到Eden区满了,会触发minor GC,对Eden区的对象和其中一个s非空闲区(s0,s1两者永远都有一方是空闲的)的对象进行回收,回收后的非垃圾对象会存到空闲的S区,如果s区放不下或者存活的对象年龄达到了阈值,就会直接进入老年代

    ‐XX:MaxTenuringThreshold 这个参数可以设置年龄的阈值,最大值是15,CMS垃圾收集器的默认值是6

    5.对象动态年龄判断:存放对象的s区,如果一批对象的大小等于该区的50%,找出这批对象的最大年龄,大于等于该年龄的对象都可以进入老年代,可以通过-XX:TargetSurvivorRatio来设置,minor gc之后触发该判断

    6. 老年代空间担保机制:

     

     -XX:-HandlePromotionFailure (jdk1.8默认就设置了)的参数是否设置了

    7. Eden区和S0,S1的比率默认是8:1:1

    参数-XX:+UseAdaptiveSizePolicy默认开启,会导致比率自动变化,可以关闭它

  • 相关阅读:
    windbg vmware win7联机调试环境搭建
    c++回调实现
    导出函数,非导出函数,公开函数,非公开函数
    fileAPI 实现移动端 添加图片 预览缩略图(自己学习)
    Ztree _ 横向显示子节点、点击文字勾选、去除指定元素input的勾选状态
    仿微信公众平台“打标签”功能~~~
    踩坑之路_"var name = ' ';"_迷之BUG
    asp.net页面生命周期《转》
    2009年软件设计师考试大纲<软考>
    typedef用法总结。
  • 原文地址:https://www.cnblogs.com/yangxiaohui227/p/15736955.html
Copyright © 2020-2023  润新知