热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

读《深入理解Java虚拟机》笔记(一)Jvm的内存区域

Jvm的内存区域图

读《深入理解Java虚拟机》笔记(一)Jvm的内存区域

一  程序计数器

是一块较小的内存空间,可以看作是当前线程所执行的字节码的行号指示器。在虚拟机的概念模型中,字节码解释器工作时就是通过改变这个技术器的值来取下一条要执行的字节码指令,分支,循环,异长,跳转,线程恢复等基础功能都需要依赖这个计数器来完成。

由于Java虚拟机的多线程是通过线程轮流切换并分配处理器执行时间的方式来实现的,在任何一个确定的时刻,一个处理器(对于多核处理器来说是一个内核)都只会执行一条线程中的指令。因此为了切换后能恢复到正确的执行位置,每条线程都需要一个独立的程序计数器,各条线程之间互不影响,独立存储,为“线程私有”型内存。

如果线程正在执行的是一个Java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址;如果正在执行的是Native方法,这个计数器的值为空(Undifined)。此内存区域是唯一一个在Java虚拟机规范中没有规定任何OutOfMemoryError情况的区域。

二 Java虚拟机栈

  Java虚拟机栈也是线程私有的,生命周期和线程相同。虚拟机栈描述的是Java方法执行的内存模型:每个方法在执行的同时都会创建一个栈帧(stack Frame)用于存储局部变量表,操作数栈,动态链接,方法出口等信息。每一个方法从调用到完成的过程,就对应着一个栈帧在虚拟机中入栈出栈的过程。

  局部变量表:存放了编译期可知的各种基本数据类型(四类八种),对象引用和returnAddress类型(执行了一条字节码指令的地址)。

  其中64位的double和long会占用2个局部变量空间(Slot),其余的数据类型只有一个。局部变量表所需的内存空间在编译期间完成分配,当进入一个方法的时候,这个方法需要在帧中分配多大的空间是完全确定的,在方法运行期间不会改变局部变量表大小。

  在Java虚拟机规范中,都这个区域规定了两种异长状况:如果线程请求的栈深度大于虚拟机所允许的深度,将抛出***Error;如果虚拟机栈可以动态拓展,拓展时无法申请到足够的内存,就会抛出OutOfMemoryError异常。

三 本地方法栈

  上段的虚拟机栈为虚拟机执行Java方法(也就是字节码)服务,而本地方法栈则为虚拟机使用到的Native方法服务。也会抛出***Error和OutOfMemoryError异常。

四  堆(heap)

  时Java虚拟机所管理的内存中最大的一块。是被所有线程共享的一块内存区域,在虚拟机启动时创建。此内存的唯一目的就是存放对象实例。也是垃圾收集器管理的主要区域。从内存回收的角度来看,由于现在的收集器大多采用分代收集算法,所以可以分为新生代和老年代,再细致一点可以分为Eden空间,From Survivor空间,To Survivor空间。从内存分配的角度来看,线程共享的Java堆中可能划分出多个线程私有的分配缓冲区(Thread Local Allocation Buffer.TLBA)。

  根据Java虚拟机的规范规定,Java堆可以处于物理上不连续的内存空间中,只要逻辑上连续的即可。当前主流的虚拟机都是按照可拓展来实现的(通过-Xms和Xms控制),如果在堆中没有内存完成实例分配,并且堆也无法拓展时,将会抛出OutOfMemoryError异常。

五 方法区

  是各个线程共享的区域,用于存储已经被虚拟机加载的类信息,常量,静态变量,即时编译后的代码等数据,对于习惯在HotSpot虚拟机上开发者来说也有可能将这个区域称为永久代。但是本质上两者是并不等价的,这个区域的内存回收目标主要是针对常量池的回收和对类型的卸载。

运行时常量池是方法区中的一部分,用于存放在编译期生成的各种字面量和符号引用。运行期间也可能将新的常量放入池中,例如String类的intern()方法

根据Java虚拟机规范规定,当方法区无法满足内存分配时,会抛出OutOfMemoryError异常。

六 直接内存

直接内存并不是虚拟机运行时数据区的一部分,也不是Java虚拟机规范中定义的内存区域。

在JDK1.4中加入了NIO类,引入了一种基于通道与缓冲区的I/o方式,它可以使用Native函数库直接分配堆外内存,然后通过一个存储在Java堆中的directByteBuffer对象作为这块内存的引用进行操作。避免了在Java堆中和Native堆中来回复制数据。

本机直接内存的分配不会受到Java堆大小的限制,但会受到本机总内存以及处理器寻址空间的限制。所以也会抛出OutOfMemoryError异常。


推荐阅读
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • 如何用JNI技术调用Java接口以及提高Java性能的详解
    本文介绍了如何使用JNI技术调用Java接口,并详细解析了如何通过JNI技术提高Java的性能。同时还讨论了JNI调用Java的private方法、Java开发中使用JNI技术的情况以及使用Java的JNI技术调用C++时的运行效率问题。文章还介绍了JNIEnv类型的使用方法,包括创建Java对象、调用Java对象的方法、获取Java对象的属性等操作。 ... [详细]
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • Java中包装类的设计原因以及操作方法
    本文主要介绍了Java中设计包装类的原因以及操作方法。在Java中,除了对象类型,还有八大基本类型,为了将基本类型转换成对象,Java引入了包装类。文章通过介绍包装类的定义和实现,解答了为什么需要包装类的问题,并提供了简单易用的操作方法。通过本文的学习,读者可以更好地理解和应用Java中的包装类。 ... [详细]
  • Java和JavaScript是什么关系?java跟javaScript都是编程语言,只是java跟javaScript没有什么太大关系,一个是脚本语言(前端语言),一个是面向对象 ... [详细]
  • 本文介绍了H5游戏性能优化和调试技巧,包括从问题表象出发进行优化、排除外部问题导致的卡顿、帧率设定、减少drawcall的方法、UI优化和图集渲染等八个理念。对于游戏程序员来说,解决游戏性能问题是一个关键的任务,本文提供了一些有用的参考价值。摘要长度为183字。 ... [详细]
  • 深入理解Java虚拟机的并发编程与性能优化
    本文主要介绍了Java内存模型与线程的相关概念,探讨了并发编程在服务端应用中的重要性。同时,介绍了Java语言和虚拟机提供的工具,帮助开发人员处理并发方面的问题,提高程序的并发能力和性能优化。文章指出,充分利用计算机处理器的能力和协调线程之间的并发操作是提高服务端程序性能的关键。 ... [详细]
  • linux进阶50——无锁CAS
    1.概念比较并交换(compareandswap,CAS),是原⼦操作的⼀种,可⽤于在多线程编程中实现不被打断的数据交换操作࿰ ... [详细]
  • ejava,刘聪dejava
    本文目录一览:1、什么是Java?2、java ... [详细]
  • Mono为何能跨平台
    概念JIT编译(JITcompilation),运行时需要代码时,将Microsoft中间语言(MSIL)转换为机器码的编译。CLR(CommonLa ... [详细]
  • vb.net不用多线程如何同时运行两个过程?不用多线程?即使用多线程,也不会是“同时”执行,题主只要略懂一些计算机编译原理就能明白了。不用多线程更不可能让两个过程同步执行了。不过可 ... [详细]
  • 线程漫谈——线程基础
    本系列意在记录Windwos线程的相关知识点,包括线程基础、线程调度、线程同步、TLS、线程池等。进程与线程理解线程是至关重要的,每个进程至少有一个线程,进程是线程的容器,线程才是真正的执行体,线程必 ... [详细]
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • 本文介绍了深入浅出Linux设备驱动编程的重要性,以及两种加载和删除Linux内核模块的方法。通过一个内核模块的例子,展示了模块的编译和加载过程,并讨论了模块对内核大小的控制。深入理解Linux设备驱动编程对于开发者来说非常重要。 ... [详细]
  • 本文讨论了在VMWARE5.1的虚拟服务器Windows Server 2008R2上安装oracle 10g客户端时出现的问题,并提供了解决方法。错误日志显示了异常访问违例,通过分析日志中的问题帧,找到了解决问题的线索。文章详细介绍了解决方法,帮助读者顺利安装oracle 10g客户端。 ... [详细]
author-avatar
手机用户2602938575
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有