JVM笔记

作者: NazgulSun | 来源:发表于2022-01-17 09:51 被阅读0次

jvm优化的一些好的文章:
https://www.jianshu.com/p/af2e21258987

1, jvm 虚拟机的old 晋升;

  • edge 分配对象,分配不下;出发垃圾回收,还是分配不下,放入old【大对象情况】
  • edge 中的对象在垃圾回收时存活,要放入to 区; 但是放不下,则放入 old 【高并发下,大量对象存活,占满 survior区】
  • 每次minGC,对survior区的对象年龄+1;当超过15,则放入old。阈值可以通过参数调整;
  • 如果survior区域内,同一年龄的对象超过空间一半,年龄大于或等于该年龄的对象就可以直接进入老年代,无须等到MaxTenuringThreshold中要求的年龄。
    这其实是一个动态预防机制,比如MaxTenuringThreshold设置的过大,原本应该晋升的对象一直停留在Survivor区,直到Survivor区溢出,
    一旦溢出发生,Eden+Svuvivor中对象将不再依据年龄全部提升到老年代,这样对象老化的机制就失效了。

2,逃逸分析

  • 如果一个对象,仅仅在一个方法中访问,不会被其他线程引用;对象可以不被在heap中被分配;而是直接在stack 空间分配,而不用给gc带来压力;
  • 分配内存和回收变快,性能变好;
  • 同时逃逸分析还可以用来优化多线程代码,如果不可能被外面的线程访问,则可以把相关的同步器取消;
    3,java8 的永久代方法区
  • 移动到了metaspace,而且metaspace不是在堆中,而是使用宿主机的内存。据说也没什么特别的原因,就是为了和jrocket保持一致;
  • class 相关的常量池和运行常量池保存在metaspace中。
  • 字符常量池,静态变量,包装常量池等都放在了堆中可以做更好的回收,也导致了intern方法在java8的改变。比如一个字符串在heap中了,比如 String a = new("abc"),那么我们就可以使用
    intern()的方法复用这个字符串,让他在运行期常量池中。 比如 String const= a.intern(); 会比 const="abc"更加节省内存;
  • 一种感觉就是class 相关的比较稳定不变放在meta,而运行时变化的,需要更好的回收的放在java heap中;

4,对象的内存布局

  • 对象头,哈希值,垃圾回收代,锁标志,偏向线程的信息;
  • 类型指针,指向meta区class的相关信息;
  • 实例数据,对象各个字段的相关信息;
  1. string相关
  • jdk9 开始,transfre char[] to byte[];代替了utf-16的固定方式,而使用 动态编码的方式来节省空间;
  • 字符串常量池,是一个hashTable;jdk7默认60013;
  • 当字符串太多的时候,常量池hashtable,冲突就会很多,会影响性能;
  • jdk8,sringtable和静态变量表都放在了heap中【和其他对象一样分配】;便于回收。
  • 常量与常量的拼接,结果在常量池,因为编译器优化;如果是常量+变量则一定是heap中,+号是StringBuilder的操作;
    final 修饰的 s1+s2,采用的也是编译器优化,不用new string;stringbuffed.append方法效率高于a+b,因为每次都会调用 newStringBuilder;
  • printstringtableStatistics可以打印 stringtable的情况,他也会做垃圾回收;
  • jvm中有很多string(25%),G1中优化了堆中string的对象,利用不可变现,可以对重复对象去重;

6.垃圾回收相关

  • mark-sweep,标记可以打对象,标记记录在对象header中,sweep遍历所有对象,check-header并且回收设置空闲;最大的问题,STW+碎片化,大对象就很难办。
  • copy算法;核心思想双存储区,eden+survie区;简单高效,无碎片;copy的时间是很长的,而且需要指针重定向;且浪费一部分空间;比较适合活的对象比较少的;
    所以新生代比较适合复制算法;老年代不太适合;
  • mark-compact算法;将存活的对象放到一端;无碎片;也是半复制算法,copy和指针重定向问题依旧存在;
  • 随着heap越来越大,一次收集会造成stw比较长,增量收集的思想开始流行,也就是一次收集一部分,多次收集类似于G1的思想;

7.垃圾回收相关概念

  • 内存泄漏,对象不再使用,但是却用无法被gc回收;通常与外部链接的一些socket,jdbc不用的时候需要关闭,否则就被浪费了;
  • stw无法避免,只是在不同的GC算法下有不同的大小;
  • 并发(concuurent)一段时间内,多个程序在同一个CPU上执行。时间片算法;并行,同一时刻有多个程序,需要多个CPU;在垃圾回收中有不同的语义;
    并行,多个线程执行回收,对应串行;并发,gc线程和用户线程;
  • 安全点,能够让程序停下来做gc的时刻;安全区域,一段带来中,对象的引用关系不会发生变化;
  • soft和弱引用等都可以设置一个引用队列,在回收的时候放入队列,可以跟踪对象回收的情况;soft引用二级缓存,弱引用可以三级缓存,gc时回收;
    虚引用,随时回收,只是用于queue来获取一个gc通知机制;
  • Cms 并发执行,初始标记,并发标记,重新标记,并发删除。两处停顿,核心在于重新标记的停顿时间,三色标记法?只能把垃圾救回来,活得变垃圾无法识别,成为浮动垃圾,只能下次才回收。并发删除阶段无法压缩,因为会修改地址。提供了一个配置参数,强制压缩,但是会加大停顿时间。cms 核心问题,碎片化和浮动垃圾。可能退化成串行回收。我们jdk8默认的是并行回收器,是一个吞吐量优先的回收器。

优化tips

  • 【eden gc时间非线性】增加 eden 大小,可降低频率,同时单次 minGC时间变化不大。因为存活的对象不会线性增加,扫描的线性时间开销较小;

相关文章

  • JVM学习笔记(3)-垃圾收集算法

    JVM学习笔记(1)-内存管理机制 JVM学习笔记(2)-内存分配与回收 垃圾收集算法 JVM垃圾收集算法有四种:...

  • JVM学习笔记

    JVM学习笔记 JVM简介 JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种...

  • Java笔记之 1. JVM学习

    一、 JVM学习笔记 JVM:Java Virtual MachineJVM总感觉那么的神秘,底层的东西,试着把一...

  • 第二周 JVM运行机制

    笔记 JVM启动流程启动过程如下图所示:bootup.png注释:jvm.cfg的用途:Controls the ...

  • JVM内存管理及垃圾回收机制

    JVM笔记 JDK:Java、JVM、Java API类库,是支持java程序开发的最小环境。JRE:Java A...

  • 【JVM篇】【JVM的组成】

    【JAVA】【JVM篇】【JVM的组成】 来自二线的码农笔记,用自己的理解总结知识点,互相学习 1. JVM概念 ...

  • ElasticSearchx

    ElasticSearch 笔记修改ES内存的占用:/etc/elasticsearch/jvm.options ...

  • Java运行时数据区

    原文戳这里JVM Run-Time Data Areas 下面是我阅读JVM规范的笔记。 1.单个线程的数据区(不...

  • JVM学习笔记之类装载器-ClassLoader

    JVM学习笔记之类装载器-ClassLoader 本文字数:2300,阅读耗时7分钟 JVM体系结构概览 类装载器...

  • JVM笔记

    一、JVM运行时划分的区域 1.程序计数器 用于存放当前线程下一个执行命令的指针。每个线程私有一个程序计数器。 2...

网友评论

    本文标题:JVM笔记

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