关于java:深入理解Java虚拟机笔记一内存划分

45次阅读

共计 1222 个字符,预计需要花费 4 分钟才能阅读完成。

Java 内存划分

Java 虚拟机在执行 Java 程序的过程中会把它所治理的内存划分为若干个不同的数据区域,如下图

一、程序计数器

程序计数器(Program Counter Register)是一块很小的内存空间,就像计算机组成原理的 PC 寄存器,它能够看作以后线程所执行的字节码的行号指示器,解释器通过扭转计数器的值来实现分支、循环等操作。为了避免线程切换之后找不到原来执行的地位,每个线程都独自领有一个程序计数器,能够称这类内存为“线程公有”内存。

二、Java 虚拟机栈

它和程序计数器一样是线程公有的,当每个办法执行的时候 Java 虚拟机都会产生一个栈帧 (Stack Frame),栈帧中存储了局部变量表(注:进入一个办法的时候,办法所须要的局部变量大小是确定的,不会再扭转)、操作数栈、动静链接、办法进口等信息)
在 Java 虚拟机创立完栈帧之后就会把它入栈到虚拟机栈中,当执行结束后就将栈帧出栈,因而当有限递归时,会发明大量的栈帧进入到虚拟机栈中,就会产生 StackOverflow 异样

public static  void stackLeak(){stackLeak();
}
public static void main(String[] args) {stackLeak();
}

运行后果为

除了上述情况,当应用的 Java 虚拟机容许动静扩大虚拟机栈的时候,就会始终申请内存扩大虚拟机栈,直到无奈申请到足够的内存,这时候便会产生 OutOfMemoryError 异样

三、本地办法栈

本地办法栈与虚拟机栈十分相似,虚拟机栈为 Java 办法提供服务,而本地虚拟机栈为本地办法服务,在栈深度溢出的时候也会产生 StackOverflowError 或者 OutofMemoryError

四、Java 堆

Java 堆与虚拟机栈不同,它是所有线程共享的一片区域,它只有一个性能就是寄存对象实例,咱们平时应用的对象变量外面寄存的则是对象地址,它指向堆中的对象实例。
始终循环生成新的对象便会造成 Java 堆溢出,而产生 OutOfMemory 异样

static class OOMObject{
}
public static void main(String[] args) {
    // 应用 list 放弃援用,避免 GC 回收对象
    List<OOMObject> list= new ArrayList<OOMObject>();
 while(true){list.add(new OOMObject());
 }
}

应用虚拟机参数 -Xms20m -Xmx20m 限度堆大小为 20m 不可扩大,运行上述程序后后果为

能够看出始终产生新对象,就会占满堆内存

五、办法区

办法区与 Java 堆一样,也是各个线程所共享的区域,它存储了每一个类的构造信息 (Class 文件),例如运行时常量池,字段和办法数据,构造函数和一般办法的字节码内容,还包含一些在类,实例,接口初始化时用到的非凡办法。
当限度办法区大小并且一直加载类文件的时候,办法区就会溢出,从而产生 OutOfMemory 异样

正文完
 0