`

深入理解java虚拟机读书笔记-第二章

    博客分类:
  • JVM
 
阅读更多

第2章 Java内存区域与内存溢出异常

 

===============运行时数据区=================================================

1.运行时数据区包含:方法区、虚拟机栈、本地方法栈、堆、程序计数器。

2.程序计数器是一块较小的内存空间,它可以看做是当前线程执行的字节码的行号指示器。在任何一个确定的时刻,一个处理器(对于多核处理器来说是一个内核)都只会执行一条线程中的指令。它是“线程私有”内存。如果线程正在执行JAVA方法,计数器记录正在执行的虚拟机字节码指令的地址;如果是NATIVE方法,则为空。

3.JAVA虚拟机栈也是线程私有的,他的生命周期与线程相同。虚拟机栈描述的是Java方法执行的内存模型;每个方法在执行的同时会创建一个栈帧,用于存储局部变量表、操作数栈、动态链接、方法出口等信息。局部变量表存放了编译器可知的各种基本数据类型(boolean,byte,char,short,int,float,long,double)、数据引用类型(reference)和返回地址returnAddress类型(指向一条字节码指令的地址)。

4.局部变量表所需要的内存空间在编译期间完成分配,当进入一个方法时,这个方法需要在桢中分配多大的局部变量空间是完全确定的,在方法运行期间不会改变局部变量表的大小。

5.对于JVM STACK,如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverFlowError,如果扩展时无法申请到足够的内存,就会抛出OutOfMemoryError异常。

6.本地方法栈和虚拟机栈发挥的作用相似,区别是JVMSTACK为java方法服务,NATIVE METHOD STACK为Native方法服务。

7.Java堆是被所有线程共享的区域,堆分为:新生代、和年老代。在细点新生代分为Eden空间、From Survivor空间、To Survivor空间。Java堆中可能划分出多个线程私有的分配缓冲区(ThreadLocal Allocation Buffer,TLAB)。Java堆可以处于物理上不连续的内存空间。

8.方法区(永久代)是各个线程共享的内存区域,它用来存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。运行时常量池(Runtime COnstant Pool)是方法区的一部分,用于存放编译器生成的各种字面量和符号引用。运行期间也可能将新的常量放入池中,例如String的.intern()方法。

9.直接内存一般不认为是运行时数据区的部分,在JDK中新加入的NIO类,引入了一种基于通道Channel与缓冲区的IO方式,他可以使用Native函数库直接分配堆外内存。

10.虚拟机需要一个new指令时,会去检查这个指令的参数能在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已经被加载、解析和初始化过。如果没有,那么必须先执行相应的类加载过程。

11.对象所需内存的大小在类加载完成后便可完全确定,为对象分配空间的任务等同于把一块确定大小的内存从Java堆中划分出来。

12.对象使用Reference来定位,reference根据JVM实现常分为两种。(1)句柄,即指向句柄池里的一个地址,句柄池包含对象实例数据指针和对象类型数据指针,句柄池再指向方法区和实例池。(2)实际地址。即指向Java堆中实际对象的地址。

 

=======================常见溢出=================================

堆溢出

1.-xms和-xmx参数用来设置堆大小的扩展范围。

2.溢出代码

List<Object>list=new ArrayList<Object>();
while(true){
   list.add(new Object());
}

 

 虚拟机栈和本地方法栈溢出

1.如果线程请求的栈深度大于虚拟机所允许的最大深度,将会StackOverFlow异常。

2如果虚拟机栈在扩展时无法申请到足够的内存空间,将会抛出OOM异常。

3.溢出代码

   使用-Xss参数减少栈内存的容量。

   定义大量的本地变量,增大此方法中本地变量表的长度。

   

/**
@author zzm
*/

public class JavaVMStackSOF{

  private int stackLength=1;

  public void stackLeak(){
     stackLength++;
     stackLeak();
  }

  public static void main(String[] args) throws Exception{
    JavaVMStackSOF javaVM=new JavaVMStackSOF ();
    javaVM.stackLeak();
}

}

 

注解:1.虽然stackLength是成员变量,但是方法执行时仍然会压栈。

           2.对于递归调用,java没有做尾递归优化。递归方法是不会使用同一栈帧的,每次递归都会压入新的栈帧。

   

方法区和运行时常量池溢出

    例如反复执行string.intern或者通过cglib创建Class

直接内存溢出

   NIO分配内存

 

附录:

http://www.oschina.net/question/12_31996 10个重要JVM参数

分享到:
评论

相关推荐

    读书笔记:深入理解Java虚拟机 JVM高级特性与最佳实践第二章笔记.zip

    读书笔记:深入理解Java虚拟机 JVM高级特性与最佳实践第二章笔记

    深入理解Java虚拟机.xmind

    自己看《深入理解Java虚拟机》(第二版)所做的一些笔记。因为个人水平有限,能够理解的也只有前面几章的内容,后面的内容觉得看了也不是很理解,就没有记在里面。希望能对大家有所帮助,也希望能和大家一起进步。

    深入java虚拟机笔记

    #### 第二章 平台无关 - **平台无关的概念**:Java的设计初衷是为了实现“一次编写,到处运行”的理念,即通过Java虚拟机使得Java程序可以在任何安装了JVM的操作系统上运行。 - **Java平台**:Java平台由Java...

    UnderstandingTheJVM:《深入理解Java虚拟机 - Jvm高级特性与最佳实践(第三版)》阅读笔记

    本repository为《深入理解Java虚拟机 - Jvm高级特性与最佳实践(第三版)》阅读笔记,因为第一章主要讲的是Java的发展历史,这里就不做笔记,直接从第2章的"Java内存区域与内存溢出异常"讲起。 第二部分 自动内存...

    java第一章笔记

    6. **跨平台性**:Java的一个重要特性就是“编写一次,到处运行”(Write Once Run Anywhere, WORA),这得益于Java的运行机制——Java程序被编译成字节码(Bytecode),然后由Java虚拟机(JVM)解释执行。...

    java学习笔记

    #### 第二章:Java基本类型变量 ##### 变量定义 - **变量**:用来存储数据的容器。 - **声明与初始化**: - 必须声明变量类型和名称。 - 可以在声明时初始化变量,也可以之后进行初始化,但必须在使用前完成。 ...

    《java程序设计习题集》读书笔记上册

    #### 第二章:Java语言特性 1. **标识符规则** - Java标识符区分大小写。 - 标识符可以由字母、数字、下划线(_)和美元符号($)组成,但不能以数字开头。 2. **字符类型** - Java采用双字节字符表示法,即`...

    java博客笔记源码

    这个压缩包包含了从第1章到第6章的Java编程笔记的源代码,旨在帮助读者深入理解Java语言的基本概念、语法和常用技术。在本文中,我们将详细探讨这些章节可能涵盖的关键知识点。 1. **Java简介** - Java的历史和...

    Java_se基础毕向东老师全程笔记

    ### 第二章:数组 - **定义**:一组有序元素的集合。 - **初始化**:创建数组并为元素赋值。 - **访问**:通过索引访问数组元素。 - **遍历**:使用循环结构遍历数组。 ### 第三章:面向对象程序开发 - **封装**:...

    java学习笔记.pdf

    #### 第二章:标识符、关键字和数据类型 - **1.8 标识符和关键字** - **标识符**:用于命名变量、方法、类等的名称。 - **关键字**:Java语言中具有特定含义的单词。 - **1.9 Java语言基本数据类型** Java的...

    java私塾学习笔记整理

    #### 第二章:基础语法 **一、关键字** Java中有53个关键字,如`public`、`private`、`protected`、`static`、`final`等,用于声明类、变量、方法等。 **二、标识符** 1. **命名规则**: - 由字母、数字、...

    毕向东_Java基础课堂笔记.pdf

    #### 第二章 数组 - 数组是用于存储固定大小的同类型元素的数据结构。 - 数组支持索引访问,可以快速定位到特定元素。 - Java中的数组通过索引访问,索引从0开始。 #### 第三章 面向对象程序开发 - 面向对象编程...

    传智播客Java_SE基础毕向东老师全程笔记

    ### 第二章:数组 - 数组是一种固定长度的数据结构,用于存储同类型元素。 - 支持一维数组、二维数组等多维数组。 - 数组操作包括声明、初始化、访问和遍历等。 ### 第三章:面向对象程序开发 - **封装**:隐藏...

    java学习笔记课后选择答案整理.doc

    进入第二章,关于Java程序的编写和执行,我们看到几个例子。第1题的程序代码是正确的Java主类,所以执行时会显示"Hello World",答案是A。第2题的主方法签名拼写错误,导致编译失败,答案是D。第3题缺少主方法的参数...

    软考-软件设计师精华知识点笔记【第二章 程序设计语言基础知识】

    在准备软件设计师考试的过程中,第二章“程序设计语言基础知识”是至关重要的部分,它涵盖了编程语言的基本概念、语法结构、程序执行原理以及常用编程范式等核心内容。本章的知识点广泛而深入,旨在帮助考生建立坚实...

    毕向东Java SE视频教程整理笔记

    #### 第二章:数组 - **数组定义**:数组是Java中用来存储固定数量的同类型元素的容器。数组的元素可以通过索引访问,索引从0开始。 - **数组初始化**:数组可以通过显式初始化或动态初始化的方式创建。显式初始化...

    core java笔记MS word版

    【第二章:标识符、关键字和类型】 1. **标识符**:是编程中用于命名的字符序列,如变量名、方法名、类名。它们遵循一定的规则,不能与Java的关键字冲突。 2. **关键字**:是Java预定义的具有特殊含义的标识符,如...

    传智播客Java SE基础毕向东老师全程笔记

    #### 第二章:数组 - **数组的概念:** 数组是一种基本的数据结构,用于存储同类型的多个元素。 - **数组的声明与初始化:** 如 `int[] arr = new int[5];`。 - **数组的访问与操作:** 可以通过索引访问和修改数组...

Global site tag (gtag.js) - Google Analytics