当前位置: 首页 > news >正文

JVM介绍

71fcee8d40dc47bb9cc6a96016cd4541.jpg程序计数器:

 

 

程序计数器属于线程的私有内存区域,记录当前线程的运行位置,以供多线程运行时上下文切换,字节码解释器通过程序计数器的增减来执行顺序分支循环等结构。独立于堆之外,因此程序计数器是唯一不会导致OutOfMemoryError的区域。

 

虚拟机栈:

 

JAVA中说得栈其实就是虚拟机栈,线程私有,每个java方法在调用时会创建一个栈帧,保存局部变量表 操作数栈 动态链接 返回地址 等信息。

 

局部变量表:基本类型以及引用类型,引用类型是指堆中对象的引用。

Stackoverflowerror指的是虚拟机栈不被允许动态扩展大小时,线程请求栈深度超过了虚拟机栈的最大深度

 

OutOfMemoryError是虚拟机栈允许动态扩展大小时,无法申请到内存空间。

 

本地方法栈:同虚拟机栈类似。在Hotspot中合二为一。

 

方法如何调用?

 

每一次方法调用,都会向虚拟机栈压入一个栈帧,而每次return或抛出异常,都会导致栈帧弹出。

 

堆:

 

线程共用,也就是线程不安全。是虚拟机最大的一块内存空间,此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例以及数组都在这里分配内存。是垃圾收集器管理的主要区域,因此也被称作GC堆。根据垃圾回收机制,将堆分为新生区、老生区。

 

最容易出现两类OutOfMemoryError,一类是垃圾回收代价太高、另一类是内存不够。

 

静态常量池:以class文件形式保存的常量,在类加载后,变为运行时常量池。

 

方法区(元空间、永久代):

 

线程共用,存放运行时常量池、静态变量、类信息等数据,在Hotspot中的实现之前为永久代,被元空间取代。元空间可以指定初始和最大空间。

 

元空间使用直接内存,若不指定最大空间,则元空间会尽可能使用物理内存,减少内存溢出

 

直接内存:

 

是在虚拟机之外的内存,由NIO类使用native方法分配,然后通过在堆中的一个引用直接内存的buffer访问

 

 

 

对象的创建:

 

虚拟机在遇到new的时候,会首先在方法区中寻找该对象的类信息是否加载,若没有加载,则首先要加载该类。

给对象分配内存,有两种方式。

指针碰撞:堆内存规整时,使用的内存和没使用的内存中间有个边界指针,把该指针往没使用过的内存上移动要分配内存的大小那么长的位置就行。

 

空闲列表:堆内存不规整时,虚拟机维护一个列表记录哪些区域是空闲的,分配的时候在列表上中找一块足够大的,然后更新记录表。

 

给分配的内存空间初始化为0。

执行初始化方法。

 

 

对象的内存布局:

 

对象的内存区域分为:对象头、实例数据、对齐填充。

 

对象头:一部分是对象的运行时数据,hashcode、分代年龄、锁状态等、一部分指向类原始数据。

 

实例数据:对象包含的真正的数据。

 

对齐填充:占位作用,使得对象占用空间为8字节的整数倍。

 

 

 

对象访问定位:

 

句柄:在堆中分配一块句柄池,reference指向这个句柄,句柄包含两个指针,一个指向对象实例数据、一个指向类型数据。

 

直接指针: reference直接指向对象实例。

 

前者:对象的内存空间被移动时只需要更改句柄而不需要更改reference

 

后者:节省了一次寻址。

 

 

 

字符串常量池:

 

对于编译期可确定值的字符串,也就是字符串常量,jvm会将其存入字符串常量池,在堆中。其他常量池在方法区

 

并且拼接得到的字符串也在编译器就存入了常量池.

 

常量折叠:将在编译期内可确定值的常量存入常量池:

 

基本数据类型以及字符串常量

final 修饰的基本数据类型和字符串变量

字符串通过 “+”拼接得到的字符串、基本数据类型之间算数运算(加减乘除)、基本数据类型的位运算(<<、>>、>>> )

因此,要 尽量避免使用new在堆上创建字符串,而使用双引号,可以引入编译器的优化。

 

 

 

String s = new String("abc");这句话创建了几个字符串对象?

 

会创建 1 或 2 个字符串:

 

如果字符串常量池中已存在字符串常量“abc”,则只会在堆空间创建一个字符串常量“abc”。

如果字符串常量池中没有字符串常量“abc”,那么它将首先在字符串常量池中创建,然后在堆空间中创建,因此将创建总共 2 个字符串对象。

相关文章:

  • R语言基础 | 安徽某高校《统计建模与R软件》期末复习
  • 力扣题目学习笔记(OC + Swift)21. 合并两个有序链表
  • oracle定位造成卡顿的SQL语句
  • Python 查杀进程的方法封装
  • ThunderSearch(闪电搜索器)_网络空间搜索引擎工具_信息收集
  • unity HoloLens2开发,使用Vuforia识别实体 触发交互(二)(有dome)
  • Hadoop入门学习笔记——五、在虚拟机中部署Hive
  • c++11 标准模板(STL)(std::pair)(七)访问 pair 的一个元素
  • 【华为OD题库-110】反转每对括号间的子串-java
  • Promise,async和js的事件循环机制
  • FPFA.一种二倍频电路代码描述以及测量详情
  • jar混淆,防止反编译,Allatori工具混淆jar包
  • springboot对接WebSocket实现消息推送
  • SpringBoot 3 集成Hive 3
  • 第十五节TypeScript 接口
  • ----------
  • php的引用
  • [译]如何构建服务器端web组件,为何要构建?
  • 【腾讯Bugly干货分享】从0到1打造直播 App
  • Angular数据绑定机制
  • Consul Config 使用Git做版本控制的实现
  • emacs初体验
  • mysql常用命令汇总
  • Object.assign方法不能实现深复制
  • SAP云平台运行环境Cloud Foundry和Neo的区别
  • spring boot 整合mybatis 无法输出sql的问题
  • Zepto.js源码学习之二
  • 百度贴吧爬虫node+vue baidu_tieba_crawler
  • 从零开始的webpack生活-0x009:FilesLoader装载文件
  • 分布式事物理论与实践
  • 湖南卫视:中国白领因网络偷菜成当代最寂寞的人?
  • 世界上最简单的无等待算法(getAndIncrement)
  • 移动端解决方案学习记录
  • - 语言经验 - 《c++的高性能内存管理库tcmalloc和jemalloc》
  • 主流的CSS水平和垂直居中技术大全
  • !!java web学习笔记(一到五)
  • # 再次尝试 连接失败_无线WiFi无法连接到网络怎么办【解决方法】
  • #[Composer学习笔记]Part1:安装composer并通过composer创建一个项目
  • $.ajax中的eval及dataType
  • (2020)Java后端开发----(面试题和笔试题)
  • (3)(3.2) MAVLink2数据包签名(安全)
  • (c语言)strcpy函数用法
  • (libusb) usb口自动刷新
  • (M)unity2D敌人的创建、人物属性设置,遇敌掉血
  • (rabbitmq的高级特性)消息可靠性
  • (附源码)springboot宠物医疗服务网站 毕业设计688413
  • (九)One-Wire总线-DS18B20
  • (原+转)Ubuntu16.04软件中心闪退及wifi消失
  • (转载)OpenStack Hacker养成指南
  • (最完美)小米手机6X的Usb调试模式在哪里打开的流程
  • * CIL library *(* CIL module *) : error LNK2005: _DllMain@12 already defined in mfcs120u.lib(dllmodu
  • .NET NPOI导出Excel详解
  • .NET 设计一套高性能的弱事件机制
  • .net 使用ajax控件后如何调用前端脚本
  • .Net程序猿乐Android发展---(10)框架布局FrameLayout