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默认开启,会导致比率自动变化,可以关闭它

原文地址:https://www.cnblogs.com/yangxiaohui227/p/15736955.html