java内存模型

  1. 线程公有:

    1. 方法区:java方法区和堆一样,方法区是一块所有线程共享的内存区域,他保存系统的类信息,比如类的字段,方法和常量池等,方法区的大小决定系统可以保存多少个类,如果系统定义的类太多,导致方法区溢出,虚拟机同样会抛出内存溢出的错误,方法区可以理解为永久区
    2. 堆:
      1. 有限分配Eden区,空间分配担保机制
      2. 大对象直接进入老年代,避免在Eden区和Servivor区之间产生大量的内存复制
      3. 对象晋升
        1. 年龄阈值:-XX:MaxTenuringThreshold,默认15
        2. 动态年龄判定:然而JVM并不总是要求对象的年龄必须达到MaxTenuringThreshold才能晋升老年代
        3. 如果在Survivor空间中相同年龄所有对象大小的总和大于Survivor空间的一半,年龄大于或等于该年龄的对象就可以直接进入老年代,而无需等到晋升年龄
  2. 虚拟机栈

    1. 局部变量表
    2. 操作数栈
      1. 主要保存计算过程的中间结果,同时做为计算过程中的变量临时的存储空间
    3. 动态链接
    4. 方法返回地址
  3. 对象生死判定

    1. 可达性分析:
      1. 方法区:类静态属性引用的对象
      2. 常量引用的对象
      3. 虚拟机栈(本地变量表)中引用的对象
      4. 本地方法栈JNI(Native方法)中引用的对象
  4. 垃圾回收算法

    1. 引用计数法
    2. 复制算法
    3. 标记清除算法
    4. 标记整理算法
  5. 垃圾回收器:

    1. serial串行
    2. paranew 并行
    3. cms并发
    4. G1
  6. serial收集器

    1. Serial收集器+Serial Old收集器:简单高效
    2. 一个线程的收集器,在进行垃圾收集的时候,必须暂停其他所有的线程直到他结束收集为止
    3. 设置参数:-XX:+UseSerialGC
    4. 开启之后会使用Serial(Young区用)+Serial Old(Old区用)的收集器组合
    5. 表示新生代和老年代都会使用串行垃圾收集器,新生代使用复制算法
  7. ParNew收集器

    1. 使用多线程进行垃圾回收,在垃圾收集时,会stw暂停其他所有的工作线程
    2. ParNew收集器其实就是Serial收集器新生代的并行多线程版本,最常见的应用场景是老年代配合CMS工作
    3. 设置参数:-XX:+UserParNewGC 启用ParNew收集器组合,新生代使用复制算法,老年代使用标记整理算法
    4. -XX:ParallelGCThreads限制线程数量,默认开启和CPU数目相同的线程数
  8. Parallel Scavenge收集器:

    1. jdk8默认的垃圾回收器
    2. Parallel Scavenge收集器类似ParNew也是一个新生代垃回收器,使用复制算法,也是一个并行的多线程的垃圾回收器,俗称吞吐量优先级的垃圾回收器,一句话,串行垃圾收集器在新生代和老年代的并行化
    3. 他关注的是:
      1. 可控的吞吐量:用户代码运行时间 / (用户代码运行时间 + 垃圾收集的时间),吞吐量高意味着高效利用CPU的时间,他多用户后台运算而不需要太多的交互任务
      2. 自适应调节策略:这也是ParallelScavenge收集器与ParNew收集器的一个重要区别
        1. 自适应调节策略,虚拟机会根据当前运行情况收集性能控制信息,动态调整这些参数以提供最合适的停顿时间(-XX:MaxGCPauseMillis)
      3. 设置参数:-XX:+UserParallelGC或 -XX:+UseParallelOldGC(相互激活),开启该参数后,新生代适用复制算法,老年代使用标记整理算法
  9. 老年代:

    1. Serial Old收集器
    2. Parallel Old收集器
    3. CMS收集器
  10. CMS收集器

    1. 优点:并发标记清楚,并发收集停顿,并发指的是与用户线程一起执行
    2. 缺点:CMS在收集与应用线程会同时增加对内存的占用,也就是CMS必须在老年代用尽之前完成垃圾回收,否则CMS回收失败时,会出现担保机制,串行老年代收集器将会以STW的方式进行一次GC,从而造成较大的停顿时间
    3. 标记清除:产生大量空间碎片,-XX:CMSFullGCsBeForeCompaction来设置多少次full gc之后进行一次整理
    4. 参数设置:-XX:+UserConcMarkSweepGC开启该参数后,会自动将-XX:+UserParNewGC打开
    5. 开启参数后:ParNew(Young区用)+CMS(Old区用) + Serial Old的收集器组合(CMS出错后的备用收集器)
    6. 四个阶段:
      1. 初始标记:STW,只是标记一下GC root能直接关联的对象,速度很快,仍然需要暂停所有的工作线程
      2. 并打标记:和用户线程一起工作,不需要暂停工作线程,主要标记过程,标记全部对象,
      3. 重新标记:STW,对之前标记的对象进行二次确认
      4. 并发清除:和并发标记这两个阶段是最耗时的
    7. 特点:
      1. CMS收集器是一种以获取最短回收停顿时间为目标的收集器,这类应用尤其重视服务器的响应速度,希望停顿时间最短
      2. CMS非常适合对内存大,CPU核数多的服务器端应用,也就是G1出现之前大型应用首选的垃圾回收器
    8. 缺点:
      1. 无法处理浮动垃圾
      2. 标记-清除:产生大量空间碎片,当然可以设置多少次GC之后进行一次整理,=0的情况下,就变成了标记-整理
  11. G1收集器

    1. 分区收集
    2. G1将整个JAVA堆划分为多个大小相等的独立区域(Region)
    3. 虽然还保留有新生代和老年代的概念,但新生代和老年代不再是物理隔离的了,他们都是一部分Region(不需要连续)的集合
    4. 分区:
      1. Eden区
      2. Survivor区
      3. Old区
      4. 超大对象区:如果一个对象占用的空间超过了分区容量的50%以上,G1收集器就认为这是一个巨型对象,这些巨型对象默认会直接分配到老年区,但是如果他是一个短期存在的巨型对象,就会对垃圾收集器产生负面影响,为了解决这个问题,G1划分了多个H区,专门用来存储巨型对象,如果一个H区存不下,会寻找多个连续的H区来存储,有时候没有连续的空间就进行Full GC
    5. 并发标记阶段:
      1. 在与应用程序并发执行的过程中会计算活跃度信息
      2. 这些活跃度信息标识出哪些Regions最适合在STW期间回收
      3. 不像CMS有清理阶段
    6. 再次标记阶段:
      1. 使用Snapshot-at-the-Beginning(STAB)算法比CMS快得多
      2. 空Region直接被回收
    7. 拷贝,清理阶段:
      1. 年轻代与老年代同时回收
      2. 老年代内存回收会基于他的活跃度信息
    8. G1收集器相对于CMS收集器的优点:
      1. G1在压缩空间方面有优势
      2. G1通过将内存空间分成区域(Region)的方式避免内存碎片问题
      3. Eden,Survivor,Old区不在固定,在内存使用效率上来说更加灵活
      4. G1可以通过设置预期停顿时间(Pause Time)来控制垃圾收集时间避免应用雪崩现象
      5. G1在回收内存后会立马同时做合并空闲内存的工作,而CMS默认是在STW的时候做
      6. G1会在Young GC中使用,而CMS只能在O区使用
  12. JVM小工具

    1. jps:打印Hotspot VM进程,VMID,JVM参数,mian()函数参数,主类名/JAR路径
    2. jstat:查看Hotspot VM运行时信息,类加载,内存,GC(可分代查看),JIT编译
    3. jinfo:查看和修改虚拟机各项配置
    4. jmap:heapdump:生成VM堆转储快照,查询finalize执行队列,Java堆和永久代详细信息
    5. jstack:查看VM当前时刻的线程快照,当前VM内每一条线程正在执行的方法堆栈集合
    6. javap:查看经javac之后产生的JVM字节码代码
    7. jcmd:一个多功能工具,可以用来导出堆,查看java进程,导出线程信息,执行GC,查看性能相关数据等
    8. jconsole:可以查看内存,线程,类,CPU信息,以及对JMX MBean进行管理
    9. jvisualvm:可以监控内存泄漏,跟踪垃圾回收,执行时内存分析,CPU分析,线程分析
  13. JVM异常

    1. java.lang.StackOverflowError:递归调用,容易导致栈溢出
    2. java.lang.OutOfMemoryError: Java heap space:对空间不足导致Java heap space
    3. java.lang.OutOfMemeryError: Direct buffer memory:nio磁盘不足导致direct buffer memory
    4. java.lang.OutOfMemoryError: GC overhead limit exceeded:频繁垃圾回收,却没有释放空间,导致GC overhead limit exceeded
    5. java.lang.OutOfMemoryError: unable to create new native thread:高并发unable create new native thread
    6. java.lang.OutOfMemeryError: Metaspace:原空间大小,只受本地内存限制
    7. java.lang.OutOfMemeryError: PermGen space:类或者方法不能被加载到老年代,他可能出现在一个程序加载很对类的时候,比如引用了很多第三方的库
    8. java.lang.OutOfMemeryError: Requested array size exceeds VM limit:创建的数组大于堆内存的空间
    9. java.lang.OutOfMemeryError: request bytes for . Out of swap space:同样是本地方法内存分配失败,只不过是JNI或者本地方法或者java虚拟机发现
  • 24
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值