zoukankan      html  css  js  c++  java
  • Java虚拟机运行时数据区

    将从《深入理解Java虚拟机:JVM高级特性与最佳实践》和 The Java® Virtual Machine Specification 中对于Java运行时数据区的描述整理记录一下

    从书中截取的Java运行时数据区

    1、程序计数器

      

    2、Java虚拟机栈

      Java虚拟机栈是线程私有的,创建线程的时候生成。存储局部变量表、局部结果。作用于方法的调用和返回
      定义了两种异常:
      1、如果一个线程的请求的栈的深度超过了Java虚拟机栈的深度,抛出StackOverflowError 。
      2、如果Java虚拟机栈可以动态扩展,尝试扩展的时候没有足够的内存,或者没有足够的内存为新线程分配虚拟机栈,则抛出OutOfMemoryError 
     
      -Xss设置设置每个栈的大小
     
     

    3、堆

      堆在虚拟机启动的时候创建,是由所有线程共享的,所有的类实例和数组都在堆上分配
      定义了一种异常:
      如果堆种没有足够的空间完成实例的分配,则抛出OutOfMemoryError 
      
      可以通过 -Xms设置堆的最小值 -Xmx设置最大值 eg:-Xmx512m
     
     
      堆是Java垃圾回收的主战场,其中又分为Eden Space(伊甸园)、Survivor Space(幸存者区)、Tenured Gen(老年代-养老区)
      1)一个对象new出来后就出现在伊甸园区无忧无虑的生活,GC会定时或者手动的来收取保护费(对象有没有引用),穷人就直接kill掉。交了保护费的对象就会进入幸存者区。
      2)并不是进入幸存者区后就安全了,但至少可以活段时间。GC还是会来进行敲诈,亿万富翁每次都给钱,GC很满意,就让其进入了Genured Gen(养老区)。万元户经不住几次敲诈就没钱了,GC看没有啥价值啦,就直接kill掉了
      3)进入到养老区的人基本就可以保证人身安全啦,但是亿万富豪有的也会挥霍成穷光蛋,只要钱没了,GC还是kill掉
      关于此区域的回收:
      IBM公司的专门研究表明,新生代中的对象98%是“朝生夕死”的,所以并不需要按照1:1的比例来划分内存空间,而是将内存分为一块较大的Eden空间和两块较小的Survivor空间,每次使用Eden和其中一块Survivor,当回收时将Eden和Servivor中还存活的对象一次性复制到另一块Survivor空间里,然后清理刚才的将Eden和Servivor空间。HotSpot虚拟机默认的Eden和Servivor的大小比例是8:1。当Servivor控件不够用时,需要依赖其他内存(老年代)进行分配担保(Handle Promotion)
    新生代中,每次垃圾收集都有大批的对象死去,只有少量存活,就使用复制算法,只需要付出少数存活对象的复制成本就可以完成收集。老年代中因为对象存活率高,没有额外空间进行分配担保,就必须使用「标记-清理」或者「标记-整理」算法来完成回收。
     

    4、方法区

      方法区在虚拟机启动的时候创建,逻辑上是堆的一部分,由所有线程共享。它存储每个类结构,运行时的常量池,字段和方法的数据,方法和构造方法。
      当方法区不能满足内存分配时,则抛出OutOfMemoryError
      常说的Perm Gen(永久代)就处于方法区。
     
      可以通过-XX:PermSize设置永久带的初始值,-XX:MaxPermSize设置永久带的最大值
     
      关于此区域的回收:
      永久带垃圾收集主要回收两部分内容:废弃常量和无用的类。回收废弃常量与Java堆种回收对象很类似,判断无用类条件比较苛刻,如下
      1)所有类的实例都已经被回收,Java种不存在任何类的实例
      2)加载该类的ClassLoader已经被回收
      3)该类对应的java.lang.Class对象没有被任何地方引用,无法通过反射访问该类的方法。
     

    5、运行时常量池

      运行时常量池是方法区的一部分。Class文件中除了有类的版本、字段、方法、接口等信息的描述外,还有一段信息是常量池,用于存放编译期生成的各种字面量和符号引用,
    这部分内容将在类加载后进入方法区的运行时常量池中存放
      当常量池无法再申请内存时,则抛出OutOfMemoryError
     

    6、本地方法栈

      本地方法栈与虚拟机栈发挥的功能类似,只是本地方法栈为native方法服务。 
      1、如果一个线程的请求的栈的深度超过了Java虚拟机栈的深度,抛出StackOverflowError 。
      2、如果Java虚拟机栈可以动态扩展,尝试扩展的时候没有足够的内存,或者没有足够的内存为新线程分配虚拟机栈,则抛出OutOfMemoryError 
     

    7、直接内存

      直接内存(DirectMemory)并不是虚拟机运行时数据区的一部分,也不是Java虚拟机规范中定义的内存区域。但是这部分内存也被频繁地使用,而且也可能导致OutOfMemoryError异常出现
         
       《深入理解Java虚拟机:JVM高级特性与最佳实践》
  • 相关阅读:
    【PQ】学会逆透视、透视,专治表格多行并一行,一行拆多行【分分合合几时休,学会了马上休】
    【Pandas】concat拼接,plan shapes are not aligned列标号不一致问题
    【MySQL】Pivot功能 一行拆多行等
    【PowerQuery】制作年底倒计时提醒
    数据分析师8大能力
    【爬虫基础】如何查看网页编码
    Mysql 插入中文错误:Incorrect string value: 'xE7xA8x8BxE5xBAx8F...' for column 'course' at row 1
    【MySQL】日期函数、时间函数总结
    mysql相关问题总结
    2020年 10月17 日 我遇见了一个很好的,善解人意的女孩
  • 原文地址:https://www.cnblogs.com/modprobe/p/6164770.html
Copyright © 2011-2022 走看看