• java自动内存管理机制


    java程序员把内存管理的工作交给虚拟机,一旦出现内存泄露或者溢出问题,如果不了解内存是怎样工作的,那么排查错误将是一件异常艰难的工作。

    java内存区域与内存溢出异常

    java运行时数据区域划分:

    线程隔离的

    1.程序计数器(Program Counter Register)

    当前线程执行代码的行号指示器,当线程切换并分配处理器执行时间,为了保证线程恢复到正确的执行位置,每个线程都有独立的计数器

    2.虚拟机栈(VM Stack)

    虚拟机栈描述的是java方法执行的内存模型:每个方式执行的同时会创建一个栈帧(Stack Frame),用于存储局部变量表、操作数栈、动态链接、方法出口等信息。

    局部变量表存放了编译期可知的基本数据类型,Reference类型,returnAddress类型。

    其中long和double占用两个slot,其他占用一个,局部变量表所需内存在编译完全确定下来, 方法运行期间不会该表局部变量表大小。

    这个区域规范了两种异常状况:

    虚拟机栈数超过虚拟机允许数量,抛StackOverflowError

    虚拟机内存扩展无法申请足够的内存空间,抛OutOfMemoryError

    3.本地方法栈(Native Method Stack)

    本地方法栈与虚拟机栈作用类似,虚拟机栈为虚拟机执行java程序服务,本地方法栈为虚拟机执行本地方法服务。

    本地方法栈也会抛出StackOverflowError,OutOfMemoryError异常。

    线程共享的

    4.堆(Heap)

    java 堆是所有线程共享的一块内存区域,在Java虚拟机规范中的描述是:The heap is the runtime data area from which memory for all class instances and arrays is allocated。

    但是随着jit编译器发展和逃逸分析技术的成熟,栈内分配,标量替换使得对象不一定放在堆中存放

    java堆是垃圾回收的主要管理区域,所以也成为GC堆,分代收集算法把内存分为一下几个区域:

    新生代

    Eden 、From Survivor、To Survivor

    老年代

    如果堆中没有内存完成分配,并且堆也无法扩展时,抛OutOfMemoryError

    5.方法区(Method Area)

    Method Area是所有线程共享的区域,存储类信息,常量信息,静态变量信息,编译后代码等。

    SpotHot虚拟机把GC分代收集扩展至方法区,方便像管理堆一样来管理方法区,所以有些人更愿意成它为“永久代”(Permanent Generation)

    这区域的回收目标主要是常量的回收和类型的卸载。

    Java虚拟机规范的规定,当方法区无法满足内存分配需求时,将抛出OutOfMemoryError异常。

    6.运行时的常量池

    运行时常量池(Runtime Constant Pool)是方法区的一部分。

    一般来说,除了保存Class文件中描述的符号引用外,还会把翻译出来的直接引用也存储在运行时常量池中 。

    运行时常量池相对于Class文件常量池的另外一个重要特征是具备动态性,用得比较多的便是String类的intern()方法

    当常量池无法再申请到内存时会抛出OutOfMemoryError异常。

    7.直接内存

  • 相关阅读:
    Interesting Finds: 2009 01.15 ~ 01.17
    Interesting Finds: 2008.12.07
    Interesting Finds: 2008.12.31
    10月16号
    10月14号
    10月15号
    10月13号
    10月20号
    10月19号
    10月12号
  • 原文地址:https://www.cnblogs.com/gengsc/p/6914327.html
Copyright © 2020-2023  润新知