深入理解java虚拟机--内存模型简记

深入理解java虚拟机-内存模型简记


写在前面: 虚拟机自动内存管理的机制下,不需要为每个new操作取写配对的delete/free代码,也不易出现内存泄漏和内存溢出问题。也正是因为把控制内存的权力交给了java虚拟机,一旦出现内存泄漏,后果很严重。因此需要了解虚拟机是怎样使用内存的。

Java虚拟机内存

运行时数据区

运行时数据区域

  • 程序计数器(线程私有)

  • 一块较小的内存空间,可以看做是当前线程执行的字节码行号的指示器。它是程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复都依赖计数器来完成。

    为什么是线程私有? java多线程的虚拟机是通过线程轮流切换、分配处理器执行时间的方式实现,因此,在切换线程时需要恢复正确的位置,所以每个线程都有一个独立的程序计数器,线程之间计数器互不影响。
    执行java方法,计数器记录的是正在执行的虚拟机字节码指令的地址;
    执行本地方法,计数器为undefined。
    没有任何OutOfMemoryError的区域
    生命周期与线程相同

  • 虚拟机栈(线程私有)

    生命周期与线程相同,每个方法创建时都会创建一个栈帧用于存储局部变量表、操作数栈、动态连接、方法出口等信息。
    局部变量存放编译期可知的各种java虚拟机基本数据类型。
    线程请求的栈深度大于虚拟机所允许的深度,抛Stack Overflow Error
    栈扩展时无法申请到足够内存会抛出out of memoryError

  • 本地方法栈(线程私有)
    本地方法栈与虚拟机栈类似,唯一不同的是两者执行的服务不同,前者为虚拟机使用的本地方法服务,而后者是为虚拟机执行Java方法服务
    有的java虚拟机会把本地方法栈和虚拟机栈合二为一。
    在栈深度溢出或扩展失败时分别抛出Stack Overflow Error 或out of memoryError


  • 虚拟机管理内存中最大的一块,java堆是被所有线程共享的一块内存区域,虚拟机启动时创建。
    用途:存放对象,几乎 所有对象都在这里分配内存。随着java逃逸分析技术 的发展,有的对象也可能在栈中分配。
    java堆是垃圾收集器管理的内存区域。也叫“GC”堆,java堆中没有完成内存实例分配且堆无法扩展时抛出OutOfMemoryError.
    逃逸分析技术:此处未作详细说明,感兴趣请参考如下这篇文章:

    https://blog.csdn.net/w372426096/article/details/80938788

  • 方法区
    线程共享。
    用途:用来存储已被类加载的类型信息、常量、静态变量、即时编译器编译后的代码缓存等数据。
    别名 非堆,与java堆区分。
    一个变动:JDK7的HotSpot已经把原本放在永久代的字符串常量池、静态变量等移出。到 JDK8完全废弃了永久代的概念,改用元空间 代替
    方法区无法满足新的内存需求分配时抛出OutOfMemoryError

    • 运行时常量池
      方法区的一部分。用于存放编译期生成的各种字面量与符号引用,在类加载后放到方法去的运行时常量池中。
  • 其他
    直接内存:并不是虚拟机运行时的一部分
    NIO:基于通道缓冲区的I/O方式,使用Native函数库直接分配堆外内存。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值