JVM基础知识_day01

JVM基础知识 基本是JVM那本书搬过来的 分类的时候暂且选择 译 了,毕竟不是原创,搬运工本工
java内存区域与内存溢出


1.java与c++比较:
java在虚拟机的帮助下,不需要为每个new操作写delete/free代码,不易出现内存泄露,直接由虚拟机管理内存。
———————————————————————————————————————————————————————
2.运行时的数据区域
java虚拟机所管理的内存包括以下运行时数据区域:
JVM基础知识_day01 虚拟机运行时数据区域
2.1程序计数器:
一块较小的内存空间,可以看做当前程序执行字节码的行号指示器。字节码解释器工作时通过改变程序计数器值来控制程序执行。
每条线程有一个独立的程序计数器以帮助线程切换后恢复到正确位置,各条线程之间程序计数器相互独立,互不影响,这块内存区域是“线程私有”的内存。
是java中唯一一个没有规定OutOfMemory的区域 。如果执行java程序,计数器记录的是字节码指令地址。如果执行native方法,计数器值为空。
2.2java虚拟机栈
java虚拟机栈也是线程私有的。生命周期与线程相同。
虚拟机栈:描述的java方法执行的内存模型。
每个方法执行的同时会创建一个栈帧,用于存储局部变量表、动态链接、操作数栈,方法出口等。
栈帧:每个方法从调用到执行结束对应一个栈帧在虚拟机入栈到出栈的过程。
局部变量表:存放编译器可以知道的各种基本数据类型、对象引用类型、returnaddress类型。局部变量表需要的内存空间在编译期间完成分配。进入一个方法之后,方法需要在帧中分配多大局部变量空间是完全确定,运行期间不会改变。
虚拟机栈中两种异常:
Stack Overflowerror:线程请求的栈深度大于虚拟机栈中允许的最大深度。
OutOfMemoryError:大部分虚拟机都是可以扩展的,扩展时无法申请到足够内存,抛出异常。
2.3 本地方法栈
本地方法栈与虚拟机栈相似,主要区别:虚拟机栈为虚拟机执行java方法服务,本地方法栈为虚拟机执行native方法服务。本地方法栈抛出异常情况与虚拟机栈一样。
2.4java堆
java虚拟机管理的内存中最大的一块,java是所有线程共享的一块区域。
创建时间:虚拟机启动时
目的:存放对象实例,几乎所有对象实例都在这里分配内存空间
Java堆:垃圾收集器管理的主要区域,很多时候称为GC堆
收集器:基本采用分代收集算法 java堆细分:新生代 老年代
java堆可以物理上不连续,逻辑上连续。
如果堆中无没存完成实例分配,堆不可以扩展时,抛出OutOfMemoryerror。
2.5 方法区
与堆一样,被线程共享
存储:类信息、常量、静态变量、即时编译器编译之后的代码等数据。该区域内存垃圾回收主要针对常量池的回收以及对类型的卸载。
方法区无法完成内存分配需求,抛出OutOfMemoryError异常。
运行时的常量池是方法区的一部分,class文件除了有类的基本信息外,还有常量池。
常量池:用于存放编译期生成的各种字面量以及符号引用他们将在类加载后进入方法区的运行时常量池中存放,除了class文件描述的富阿红引用外,还会把翻译出来的直接引用存储在运行是的常量池中。(字面量 例如:int i=1 1就是字面量; 符号引用:包含能唯一定位到类、接口、方法、字段的信息 直接引用:指向目标的指针、偏移量、句柄)
运行时常量池相对于class文件常量池:具备动态性。常量不是只有编译期间才能产生,也不是只有预class文件的常量池内容才能进入方法区运行时常量池,运行期间也可以将新的常量放入池中。用的比较多的,String的intern()
运行时常量池是方法区的一部分。