【深入理解JVM】学习笔记——-2、自动内存管理机制

本文深入探讨JVM的自动内存管理机制,包括运行时数据区的各个部分如堆、栈、方法区等,以及内存溢出异常的类型和处理方式。针对Java堆、虚拟机栈、本地方法栈、直接内存等区域的内存分配、对象创建过程进行了详细阐述,并列举了不同服务器环境下内存溢出的处理方法,如Tomcat中的 PermGen space 问题、WebLogic和Resin的解决方案。
摘要由CSDN通过智能技术生成

第二部分  自动内存管理机制

二、内存区域和内存溢出异常

1、运行时数据区

  程序计数器

  • 记录的是正在执行的虚拟机字节码指令的地址,是一块较小的内存空间,可以看成是当前线程所执行的字节码的行号指示器,每个线程都有一个独立的程序计数器,各条线程的程序计数器互不影响,独立存储,这类内存区域成为“线程私有的内存”。
  • 程序计数器内存区域是唯一在虚拟机规范中没有OutOfMemoryError的情况的区域

  Java虚拟机栈

  • 同程序计数器一样,也是线程私有的。每个方法在执行的时候都会创建一个栈帧,用于存储局部变量表、操作数栈、动态链接、方法出口等信息。
  • 每一个方法从调用直至执行完成的过程,都对应着一个栈帧在虚拟机栈中入栈和出栈的过程。
  • 局部变量表所需的内存空间在编译期间完成分配,当进入一个方法时,这个方法需要在栈帧中分配多大的局部变量空间是完全确定的,在方法运行期间不会改变局部变量表的大小。
  • 如果请求的栈深度超过虚拟机锁允许的深度,将抛出StackOverFlowError异常。如果拓展无法申请到足够的内存,将抛出OutOfMemoryError异常。

  本地方法栈

  • 为虚拟机使用的native方法服务,和虚拟机栈一样,本地方法栈也会抛出StackOverFlowError和OutOfMemoryError异常。

  Java堆

  • Java堆是JAVA虚拟机所管理的内存中最大的一块,是被所有线程共享的一块内存区域,用来存放对象实例,几乎所有的对象实例都在这里分配。
  • Java堆是垃圾回收的主要区域,称为“GC堆”采用分代收集算法。
  • Java堆还可以细分为新生代和老年代,新生代在细致一点分为Eden,From Survivor,To Survivor空间。
  • 如果堆中无法完成对象实例的内存分配,且堆也无法扩展时,将抛出OutOfMemoryError异常。

  方法区

  • 方法去与JAVA堆一样,是各个线程共享的内存区域,用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据,HotSpot虚拟机的设计团队把GC分代收集扩展至方法区,或者说使用永久代来代替方法区。
  • 在目前已经发布的JDK1.7的HotSpot中,已经把原本放在永久代的字符串常量池移出了。当方法区无法满足内存的分配需求时,将抛出OutOfMemoryError异常。

  运行时常量池

  • 是方法区的一部分,Class文件除了有类的版本、字段、方法、接口等描述信息外,还有一项信息是常量池,用于存放编译器生成的各种字面量和符号引用,这部分内容将在类加载后进入方法区的运行时常量池存放。
  • 运行时常量池相对于Class文件常量池,具有动态性,运行期间也可以将新的常量放入常量池,比如String类的intern()方法。
  • 当运行时常量池无法申请到更多的内存时,将会抛出Out
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值