java_JVM

JVM内存模型


JVM内存模型你只要看这一篇就够了
https://www.jianshu.com/p/c9ac99b87d56
程序猿的日常——JVM内存模型与垃圾回收
https://www.cnblogs.com/xing901022/p/7725961.html

image.png
image.png

方法区位置


  • jdk1.7
    方法区相当于永久带

  • jdk 1.8
    元空间(Metaspace)来代替原来的永久带。
    方法区相当于元空间。
    不过元空间与永久代之间最大的区别在于:元空间并不在虚拟机中,而是使用本地内存。因此,默认情况下,元空间的大小仅受本地内存限制,但可以通过参数来指定元空间的大小。
    为什么要移出永久带:
    永久代的大小指定比较困难,太小容易出现永久代溢出,太大则容易导致老年代溢出。

方法区


Java运行时,各种类型存储介绍

存放class类对象:
1.类的基本信息
2.方法信息
3.常量池
4.静态变量

  • 堆与栈分开设计是为什么呢?
    1.栈存储了处理逻辑、堆存储了具体的数据,这样隔离设计更为清晰
    2.堆与栈分离,使得堆可以被多个栈共享。
    3.栈保存了上下文的信息,因此只能向上增长;而堆是动态分配
    栈的大小可以通过-XSs设置,如果不足的话,会引起java.lang.StackOverflowError的异常。

垃圾回收


  • 堆分代


    image.png

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

  • 新生代垃圾回收过程

    当触发minor GC时,会先把Eden中存活的对象复制到to Survivor中;
    然后再看from survivor,如果次数达到年老代的标准,就复制到年老代中;如果没有达到则复制到to survivor中,如果to survivor满了,则复制到年老代中。
    然后调换from survivor 和 to survivor的名字,保证每次to survivor都是空的等待对象复制到那里的。

垃圾收集器


参考
http://blog.csdn.net/tjiyu/article/details/53983650

  • 新时代收集器
    1.串行收集器 Serial
    2.并行收集器 Parallel(并行)
    3.ParNew(并行)

  • 老年代收集器
    1.Serial Old
    2.Parallel Old(并行)
    3.CMS(并发标记清除收集器 Concurrent Mark Sweep Collector)

  • 整堆收集器:G1(Garbage First Collector, 并发)

  • 并行(用户线程仍然处于等待状态)
    指多条垃圾收集线程并行工作,但此时用户线程仍然处于等待状态
  • 并发
    指用户线程与垃圾收集线程同时执行(但不一定是并行的,可能会交替执行);
    用户程序在继续运行,而垃圾收集程序线程运行于另一个CPU上;
image.png
  • Minor GC和Full GC的区别
    • Minor GC
      又称新生代GC,指发生在新生代的垃圾收集动作;
      因为Java对象大多是朝生夕灭,所以Minor GC非常频繁,一般回收速度也比较快;
    • Full GC
      又称Major GC或老年代GC,指发生在老年代的GC;
      出现Full GC经常会伴随至少一次的Minor GC(不是绝对,Parallel Sacvenge收集器就可以选择设置Major GC策略);
      Major GC速度一般比Minor GC慢10倍以上;

频繁GC优化


http://www.cnblogs.com/xing901022/p/9084941.html

  • 新生代的垃圾回收模式
image.png

由于JVM设计者认为,大部分的对象都是新创建的,生命周期都不长。因此新建的对象会直接放在新生代中,并采用复制回收机制。即保证to区总是空的,每次触发GC的时候,就会把Eden和from survivor中的还存活的对象拷贝到to区中。然后to变成了from,from变成to。这样反复几次,还存活的对象,就会拷贝到old老年代当中。

在配置JVM的时候就有几个比较重要的参数:

-Xms 和 -Xmx 配置了堆的最小和最大内存
-XX:NewSize 和 -XX:MaxNewSize 配置了新生代的内存。最大是Xmx的一半,不过最好还是看业务场景
-XX:NewRatio 设置新生代和老年代的比例,如 -XX:NewRatio=3 指定老年代/新生代为3/1
-XX:SurvivorRatio 设置survivor与eden的比例,如 -XX:SurvivorRatio=10 表示eden是survivor的10倍,即survivor每个占1/12,eden占10/12
-XX:InitialTenuringThreshold, -XX:MaxTenuringThreshold and -XX:TargetSurvivorRatio 控制进入老年代的条件,例如 , -XX:MaxTenuringThreshold=10 -XX:TargetSurvivorRatio=90 设定老年代阀值的上限为10,幸存区空间目标使用率为90%
-XX:+NeverTenure and -XX:+AlwaysTenure 分别表示永远不进入老年代,和一次GC存活就进入老年代

你可能感兴趣的:(java_JVM)