Java - JVM

本贴最后更新于 2370 天前,其中的信息可能已经时移世易

    本文主要是记录在学习 Java - JVM 过程中的一些知识点备忘!

知识点规整:

一、

  • 介绍下 Java 内存区域(运行时数据区):程序计数器、虚拟机栈、本地方法栈、堆、方法区、运行时常量池、直接内存

  • Java 对象的创建过程:五步,需要能够默认出来并且知道每一步虚拟机都做了些什么

  • 对象的访问定位的两种方式:句柄、直接指针

  • String 类和常量池

  • 8 种基本类型的包装类和常量池

20181223-1

1、运行时数据区域

Java 虚拟机在执行 java 程序的过程中会把它管理的内存划分成若干个不同的数据区域:有些区域是线程私有的(程序计数器、虚拟机栈、本地方法栈),有些区域是线程共享的(堆、方法区、直接内存)

1.1、程序计数器

程序计数器是一块较小的内存空间,可以看作是当前线程锁执行的字节码的行号指示器!

字节码解释器工作时通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等功能都需要依赖这个计数器来完成!

另外,为了线程切换后能够恢复到正确的执行位置,每个线程都需要一个独立的程序计数器,各个线程之间计数器互不影响,独立存储,因此这类内存区域也被称为"线程私有"的内存!

程序计数器的作用主要有两个:

  • 字节码解释器通过改变程序计数器来依次读取指令,从而实现代码的流程控制,如:顺序执行、选择、循环、异常处理
  • 在多线程的情况下,程序计数器用于记录当前线程执行的位置,从而当线程切换回来的时候能够知道该线程上次运行到哪儿了

注意:程序计数器是唯一一个不会出现 OutOfMemoryError 的内存区域,它的生命周期随着线程的创建而创建,随着线程的结束而死亡

1.2、java 虚拟机栈

与程序计数器一样,java 虚拟机栈也是线程私有的,它的生命周期与线程相同,描述的是 java 方法执行的内存模型

java 内存可以粗略低区分为堆内存(Heap)和栈内存(Stack),其中栈也即现在说的虚拟机栈,或者说是虚拟机栈中局部变量表部分(实际上,java 虚拟机栈是由一个个栈帧组成,而每个栈帧都拥有:局部变量表、操作数栈、动态链接、方法出口信息)

局部变量表主要用于存放编译器可知的各种数据类型(boolean、byte、char、short、int、float、long、double)、对象引用(reference 类型,它不同于对象本身,可能是一个指向对象起始地址的引用指针,也可能是指向一个代表对象的句柄或其他与此对象相关的位置)

java 虚拟机栈会出现两种异常:StackOverFlowError 和 OutOfMemoryError

  • StackOverFlowError:若 java 虚拟机栈的内存大小不允许动态扩展,那么当线程请求栈的深度超过当前 java 虚拟机栈的最大深度的时候,则抛出该异常
  • OutOfMemoryError:若 java 虚拟机栈的内存大小允许动态扩展,那么当线程请求栈时内存用完了,无法再动态扩展了,则会抛出该异常

java 虚拟机栈也是线程私有的,每个线程均有各自的 java 虚拟机栈,而且随着线程的创建而创建,随着线程的死亡而死亡

1.3 本地方法栈

与虚拟机栈所发挥的作用非常相似,区别在于:虚拟机栈为虚拟机执行 java 方法(也就是字节码)服务,而本地方法栈则为虚拟机使用到的 Native 方法服务!在 HotSpot 虚拟机中,本地方法栈与 Java 虚拟机栈合二为一!

本地方法被执行的时候,在本地方法栈也会创建一个栈帧,用于存放该本地方法的局部变量表、操作数栈、动态链接、出口信息

方法执行完毕后相应的栈帧也会出栈并释放内存空间,也会出现 StackOverFlowError 和 OutOfMemoryError 两种异常

1.4、堆

Java 虚拟机所管理的内存中最大的一块,java 堆是所有线程共享的一块内存区域,在虚拟机启动时创建!此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例以及数组均在这里分配内存

Java 堆是垃圾回收器管理的主要区域,因此也被称作 GC 堆!从垃圾回收角度出发,由于现在垃圾收集器基本上都是采用分代垃圾收集算法,因此 java 堆也还可以细分为“新生代和老年代(以及 jdk1.7 之前还有:永久代)”,再细致一点新生代可以细分“Eden 空间、From Survivor、To Survivor 空间等”,进一步划分的目的是为了更好地回收内存或者说更快地分配内存

在 JDK1.8 中移除了整个永久代,取而代之的是一个叫元空间(Metaspace)的区域(永久代使用的是 JVM 的堆内存空间,而元空间使用的是物理内存,直接受到本机的物理内存限制)

1.5、方法区

方法区与 java 堆一样,是各个线程共享的内存区域,它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据!

虽然 java 虚拟机规范把方法区描述为堆的一个逻辑部分,但是它却有一个别名 Non-Heap(非堆),目的是为了与 java 堆区分开来

HotSpot 虚拟机中方法区也常被称为“永久代”,本质上两者并不等价!仅仅是因为 HotSpot 虚拟机设计团队用永久代来实现方法区而已,这样 HotSpot 虚拟机的垃圾收集器就可以像管理 java 堆一样管理这部分内存了!但这并不是一个好主意,因为这样更容易遇到内存溢出问题

相对而言,垃圾收集行为在这个区域是比较少出现的,但并非数据进入方法区后就“永久存在”了

1.6 运行时常量池

运行时常量池是方法区的一部分。Class 文件中除了有类的版本、字段、方法、接口等描述信息外,还有常量池信息(用于存放编译期生成各种字面量和符合引用)

既然运行时常量池是方法区的一部分,自然受到方法区内存的限制,当常量池无法再申请到内存时会抛出 OutOfMemoryError 异常

JDK1.7+ 版本 JVM 已经将运行时常量池从方法区中移了出来,在 Java 堆中开辟了一块区域存放运行时常量池

1.7、直接内存

直接内存并不是虚拟机运行时数据区的一部分,也不是虚拟机规范中定义的内存区域,但是这部分内存也被频繁地使用,而且也可能导致 OutOfMemoryError 异常出现

JDK1.4 中新加入的 NIO(New Input/Output)类,引入了一种基于通道 Channel 与缓存区 Buffer 的 I/O 方式,它可以直接使用 Native 函数库直接分配堆外内存,然后通过一个存储在 Java 堆中的 DirectByteBuffer 对象作为这块内存的引用进行操作!!这样能够在一些场景中显著提高性能,因为避免了在 Java 堆和 Native 堆之间来回复制数据

本机直接内存的分配不会收到 Java 堆的限制,但是,既然是内存就会受到本机总内存大小以及处理器寻址空间的限制

  • 学习

    “梦想从学习开始,事业从实践起步” —— 习近平

    172 引用 • 534 回帖
  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3201 引用 • 8216 回帖 • 3 关注
  • 面试

    面试造航母,上班拧螺丝。多面试,少加班。

    326 引用 • 1395 回帖 • 2 关注

相关帖子

回帖

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...

推荐标签 标签

  • 宕机

    宕机,多指一些网站、游戏、网络应用等服务器一种区别于正常运行的状态,也叫“Down 机”、“当机”或“死机”。宕机状态不仅仅是指服务器“挂掉了”、“死机了”状态,也包括服务器假死、停用、关闭等一些原因而导致出现的不能够正常运行的状态。

    13 引用 • 82 回帖 • 73 关注
  • Latke

    Latke 是一款以 JSON 为主的 Java Web 框架。

    71 引用 • 535 回帖 • 829 关注
  • 工具

    子曰:“工欲善其事,必先利其器。”

    298 引用 • 763 回帖
  • 互联网

    互联网(Internet),又称网际网络,或音译因特网、英特网。互联网始于 1969 年美国的阿帕网,是网络与网络之间所串连成的庞大网络,这些网络以一组通用的协议相连,形成逻辑上的单一巨大国际网络。

    98 引用 • 367 回帖
  • 周末

    星期六到星期天晚,实行五天工作制后,指每周的最后两天。再过几年可能就是三天了。

    14 引用 • 297 回帖 • 4 关注
  • 黑曜石

    黑曜石是一款强大的知识库工具,支持本地 Markdown 文件编辑,支持双向链接和关系图。

    A second brain, for you, forever.

    24 引用 • 242 回帖 • 2 关注
  • Unity

    Unity 是由 Unity Technologies 开发的一个让开发者可以轻松创建诸如 2D、3D 多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

    25 引用 • 7 回帖 • 119 关注
  • 电影

    这是一个不能说的秘密。

    122 引用 • 608 回帖
  • Hexo

    Hexo 是一款快速、简洁且高效的博客框架,使用 Node.js 编写。

    22 引用 • 148 回帖 • 6 关注
  • OpenCV
    15 引用 • 36 回帖 • 7 关注
  • 禅道

    禅道是一款国产的开源项目管理软件,她的核心管理思想基于敏捷方法 scrum,内置了产品管理和项目管理,同时又根据国内研发现状补充了测试管理、计划管理、发布管理、文档管理、事务管理等功能,在一个软件中就可以将软件研发中的需求、任务、bug、用例、计划、发布等要素有序的跟踪管理起来,完整地覆盖了项目管理的核心流程。

    10 引用 • 15 回帖 • 9 关注
  • 单点登录

    单点登录(Single Sign On)是目前比较流行的企业业务整合的解决方案之一。SSO 的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。

    9 引用 • 25 回帖 • 4 关注
  • jsDelivr

    jsDelivr 是一个开源的 CDN 服务,可为 npm 包、GitHub 仓库提供免费、快速并且可靠的全球 CDN 加速服务。

    5 引用 • 31 回帖 • 105 关注
  • 分享

    有什么新发现就分享给大家吧!

    248 引用 • 1794 回帖 • 1 关注
  • NGINX

    NGINX 是一个高性能的 HTTP 和反向代理服务器,也是一个 IMAP/POP3/SMTP 代理服务器。 NGINX 是由 Igor Sysoev 为俄罗斯访问量第二的 Rambler.ru 站点开发的,第一个公开版本 0.1.0 发布于 2004 年 10 月 4 日。

    315 引用 • 547 回帖 • 1 关注
  • 心情

    心是产生任何想法的源泉,心本体会陷入到对自己本体不能理解的状态中,因为心能产生任何想法,不能分出对错,不能分出自己。

    59 引用 • 369 回帖 • 1 关注
  • Linux

    Linux 是一套免费使用和自由传播的类 Unix 操作系统,是一个基于 POSIX 和 Unix 的多用户、多任务、支持多线程和多 CPU 的操作系统。它能运行主要的 Unix 工具软件、应用程序和网络协议,并支持 32 位和 64 位硬件。Linux 继承了 Unix 以网络为核心的设计思想,是一个性能稳定的多用户网络操作系统。

    954 引用 • 944 回帖
  • 自由行
    2 关注
  • 强迫症

    强迫症(OCD)属于焦虑障碍的一种类型,是一组以强迫思维和强迫行为为主要临床表现的神经精神疾病,其特点为有意识的强迫和反强迫并存,一些毫无意义、甚至违背自己意愿的想法或冲动反反复复侵入患者的日常生活。

    15 引用 • 161 回帖 • 2 关注
  • OpenStack

    OpenStack 是一个云操作系统,通过数据中心可控制大型的计算、存储、网络等资源池。所有的管理通过前端界面管理员就可以完成,同样也可以通过 Web 接口让最终用户部署资源。

    10 引用 • 1 关注
  • 持续集成

    持续集成(Continuous Integration)是一种软件开发实践,即团队开发成员经常集成他们的工作,通过每个成员每天至少集成一次,也就意味着每天可能会发生多次集成。每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽早地发现集成错误。

    15 引用 • 7 回帖
  • Firefox

    Mozilla Firefox 中文俗称“火狐”(正式缩写为 Fx 或 fx,非正式缩写为 FF),是一个开源的网页浏览器,使用 Gecko 排版引擎,支持多种操作系统,如 Windows、OSX 及 Linux 等。

    7 引用 • 30 回帖 • 385 关注
  • 书籍

    宋真宗赵恒曾经说过:“书中自有黄金屋,书中自有颜如玉。”

    81 引用 • 409 回帖
  • Sublime

    Sublime Text 是一款可以用来写代码、写文章的文本编辑器。支持代码高亮、自动完成,还支持通过插件进行扩展。

    10 引用 • 5 回帖 • 2 关注
  • RemNote
    2 引用 • 16 回帖 • 20 关注
  • WiFiDog

    WiFiDog 是一套开源的无线热点认证管理工具,主要功能包括:位置相关的内容递送;用户认证和授权;集中式网络监控。

    1 引用 • 7 回帖 • 613 关注
  • 七牛云

    七牛云是国内领先的企业级公有云服务商,致力于打造以数据为核心的场景化 PaaS 服务。围绕富媒体场景,七牛先后推出了对象存储,融合 CDN 加速,数据通用处理,内容反垃圾服务,以及直播云服务等。

    29 引用 • 230 回帖 • 124 关注