b+树的原理
Java 内存区域
<ignore_js_op>![]()
Heap
线程公有
存放实例对象
是GC主要管理区域,因此可以更细致的划分为:新生代、老年代
再细致一点划分:Eden区、From Survivor区、To Survivor区
内存空间:可以物理上不连续、逻辑上连续即可。
Method Area
线程公有
主要存储:类信息、常量、静态变量、编译后的代码
运行时常量池
主要存储:编译期的字面量以及符号引用
具有动态性,即可以在运行时将常量放入池中。
VM Stack
线程私有
主要包括:
局部变量表:存放编译期的各种基本数据类型、对象引用、returnAddress类型
操作数栈:每一个元素可以为任意的java类型,32位数据类型所占容量为1,64位数据类型所占容量为2
动态连接:class文件的常量池中有大量的符号引用,这些符号引用有一部分是在类加载阶段或者在第一次使用的时候就转换为直接引用,这部分成为静态解析。另一部分是每一次运行的时候转化为直接引用,这部分即为动态连接。
方法出口:例如A方法中调用了B方法,B方法的返回值压入A方法的栈帧中。
Native Method Stack
线程私有
与VM Stack相似,唯一区别在于该栈为Native方法服务。
Hot Spot 将VM Stack 与 Native Method Stack 合而为一。
Program Counter Register
线程私有
用于记录线程执行字节码的指令的地址。
Direct Memory
NIO中使用直接内存,提高效率。
对象创建过程
<ignore_js_op>![]()
- 首先当虚拟机遇到一条new指令时,先去检查该符号引用代表的类是否已经完成类加载,若未完成,则执行以下步骤
- 类加载
- 为对象分配内存
分配方式:指针碰撞/空闲列表
线程安全:CAS解决 - 虚拟机初始化内存空间
- 虚拟机对对象进行必要的设置
- 执行完成初始化
- 对象创建完成
对象内存布局<ignore_js_op>![]()
第一部分用于存储对象自身的运行时数据,如哈希码(HashCode)、GC 分代年龄、锁状态标志、线程持有的锁、偏向线程 ID、偏向时间戳、对象分代年龄,这部分信息称为“Mark Word”;Mark Word 被设计成一个非固定的数据结构以便在极小的空间内存储尽量多的信息,它会根据自己的状态复用自己的存储空间。
第二部分是类型指针,即对象指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例;
如果对象是一个 Java 数组,那在对象头中还必须有一块用于记录数组长度的数据。因为虚拟机可以通过普通 Java 对象的元数据信息确定 Java 对象的大小,但是从数组的元数据中无法确定数组的大小。
在 32 位系统下,存放 Class 指针的空间大小是 4 字节,Mark Word 空间大小也是4字节,因此头部就是 8 字节,如果是数组就需要再加 4 字节表示数组的长度,如下表所示:
<ignore_js_op>![]()
在 64 位系统及 64 位 JVM 下,开启指针压缩,那么头部存放 Class 指针的空间大小还是4字节,而 Mark Word 区域会变大,变成 8 字节,也就是头部最少为 12 字节,如下表所示:
<ignore_js_op>![]()
压缩指针:开启指针压缩使用算法开销带来内存节约,Java 对象都是以 8 字节对齐的,也就是以 8 字节为内存访问的基本单元,那么在地理处理上,就有 3 个位是空闲的,这 3 个位可以用来虚拟,利用 32 位的地址指针原本最多只能寻址 4GB,但是加上 3 个位的 8 种内部运算,就可以变化出 32GB 的寻址。
对象访问定位
两种方式:
句柄池:引用中存储的是句柄地址,当实例对象移动时,只需要改变句柄对应的指针,不需要改变引用本身,比较稳定。
直接指针:速度快,节省了一次指针定位的开销。
常用指令
invokeinterface:用以调用接口方法,在运行时搜索一个实现了这个接口方法的对象,找出适合的方法进行调用。
invokevirtual:指令用于调用对象的实例方法,根据对象的实际类型进行分派
invokestatic:用以调用类方法
invokespecial:指令用于调用一些需要特殊处理的实例方法,包括实例初始化方法、私有方法和父类方法。
invokedynamic:JDK1.7新加入的一个虚拟机指令,相比于之前的四条指令,他们的分派逻辑都是固化在JVM内部,而invokedynamic则用于处理新的方法分派:它允许应用级别的代码来确定执行哪一个方法调用,只有在调用要执行的时候,才会进行这种判断,从而达到动态语言的支持。
基于栈的指令集 && 基于寄存器的指令集
java采用的是基于栈的指令集,这种指令集依赖操作数栈进行工作
优点:
可移植:由于寄存器是由硬件直接提供的,所以程序如果依赖寄存器不可避免的会受到硬件的约束
程序代码紧凑
编译器实现简单
缺点:
速度慢
指令数量多:完成相同功能所需的指令比寄存器架构多,因为光是入栈、出栈就已经很多指令了
内存访问多:频繁的栈访问意味着频繁的内存访问,而对于处理器来说,内存始终是速度的瓶颈。
Java内存溢出异常
内存溢出
堆上无内存可完成实例分配且堆无法扩展时:java.lang.OutOfMemoryError: Java heap space
方法区以及内存的常量池无法满足内存分配需求时:java.lang.OutOfMemoryError: PermGen space
栈扩展时无法申请足够内存:java.lang.StackOverflowError
内存泄漏
代码设计引起的程序动态分配的内存没有释放,导致该部分内存不可用
内存溢出与内存泄漏的区别
内存泄漏是导致内存溢出的原因之一,内存泄漏积累起来就会导致内存溢出
内存泄漏可以通过完善代码来解决,内存溢出无法彻底避免,只能通过配置来减少发生的频率
内存泄漏内存溢出的检查
性能监测工具:
JProfiler
Optimizeit Profiler
Eclipse Memory Analyzer
EclipseMAT
JProbe
更多java学习资料可关注:itheimaGZ获取
b+树的原理的更多相关文章
- 梯度提升树(GBDT)原理小结(转载)
在集成学习值Adaboost算法原理和代码小结(转载)中,我们对Boosting家族的Adaboost算法做了总结,本文就对Boosting家族中另一个重要的算法梯度提升树(Gradient Boos ...
- 回归树的原理及Python实现
大名鼎鼎的 GBDT 算法就是用回归树组合而成的.本文就回归树的基本原理进行讲解,并手把手.肩并肩地带您实现这一算法. 1. 原理篇 1.1 最简单的模型 如果预测某个连续变量的大小,最简单的模型之一 ...
- B树,B+树的原理及区别
如图所示,区别有以下两点: 1. B+树中只有叶子节点会带有指向记录的指针(ROWID),而B树则所有节点都带有,在内部节点出现的索引项不会再出现在叶子节点中. 2. B+树中所有叶子节点都是通过指针 ...
- 浅谈可持久化Trie与线段树的原理以及实现(带图)
浅谈可持久化Trie与线段树的原理以及实现 引言 当我们需要保存一个数据结构不同时间的每个版本,最朴素的方法就是每个时间都创建一个独立的数据结构,单独储存. 但是这种方法不仅每次复制新的数据结构需要时 ...
- 梯度提升树(GBDT)原理小结
在集成学习之Adaboost算法原理小结中,我们对Boosting家族的Adaboost算法做了总结,本文就对Boosting家族中另一个重要的算法梯度提升树(Gradient Boosting De ...
- CART(分类回归树)原理和实现
前面我们了解了决策树和adaboost的决策树墩的原理和实现,在adaboost我们看到,用简单的决策树墩的效果也很不错,但是对于更多特征的样本来说,可能需要很多数量的决策树墩 或许我们可以考虑使用更 ...
- hdu 3303 Harmony Forever (线段树 + 抽屉原理)
http://acm.hdu.edu.cn/showproblem.php?pid=3303 Harmony Forever Time Limit: 20000/10000 MS (Java/Othe ...
- 毕达哥拉斯树(pythagorasTree)原理解析及canvas动画实现
以前就看到了这个东西,由于太忙了最近才有时间来实现这个; 该文章适合有一定 canvas 基础的人阅读; 首先说说他的原理: The construction of the Pythagoras tr ...
- mysql系列十、mysql索引结构的实现B+树/B-树原理
一.MySQL索引原理 1.索引背景 生活中随处可见索引的例子,如火车站的车次表.图书的目录等.它们的原理都是一样的,通过不断的缩小想要获得数据的范围来筛选出最终想要的结果,同时把随机的事件变成顺序的 ...
- GBDT(梯度提升树) 原理小结
在之前博客中,我们对Boosting家族的Adaboost算法做了总结,本文就对Boosting家族中另一个重要的算法梯度提升树(Gradient Boosting Decison Tree, 以下简 ...
随机推荐
- JS高级学习笔记(10) 之 js 时怎么解析HTML标签的
DOM 节点类型 浏览器渲染过程 浏览器是怎么把HTML标签语言和JavaScript联系在一起的,这就是我们常说的DOM. 浏览器中的DOM解析器把HTML翻译成对象(object),然后JavaS ...
- UML-设计模式-对一组相关的对象使用抽象工厂模式
1.场景 问题: javapos驱动,有2套,一套是IBM的,另一套是NCR的.如: 使用IBM硬件时要用IBM的驱动,使用NCR的硬件时要用NCR的驱动.那该如何设计呢? 注意,此处需要创建一组类( ...
- ACWING基础算法(三)
双指针算法. 相向双指针,指的是在算法的一开始,两根指针分别位于数组/字符串的两端,并相向行走. ACWING 的一道裸题(不知道为啥进不去404):最长连续不重复子序列 输入 5 1 2 2 3 5 ...
- 一天一个设计模式——工厂方法(FactoryMethod)模式
一.模式说明 在前一个模板方法(Template Method)模式中,父类定义了处理流程,而流程中用到的方法交给子类去实现.类似的,在工厂方法模式中,父类决定如何生成实例,但并不决定所要生成的具体类 ...
- Spring装配Bean的一些高级技巧
一.使用@Profile注解来实现在不同环境下创建不同的Bean 实现方式:将不同的Bean定义整理到对应环境的Profile中,当应用部署到不同的环境时(开发环境或者是QA环境或者是生产环境),激活 ...
- unix中嘚vim编辑器
在linux家族中,vim编辑器是系统自带的文本编辑器,其功能强大自不必说了. 偶有小白,刚接触linux,要修改某个文本文件,不可能像WINDOWS那样操作,更有甚者,进入VI编辑器后,无法退出以致 ...
- jQuery 1.3.2 简单实现select二级联动
jQuery 1.3.2 简单实现select二级联动 复制代码代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transiti ...
- 实验吧web-易-what a fuck!这是什么鬼东西?
打开链接是一大串符号,是js编码的一种,全部复制下来,粘贴在控制台中回车就拿到flag了.
- Bugku 逆向
1.入门逆向 下载解压,在文件夹中打开命令行窗口执行一下:baby.exe 发现输出了一串字符,在将其放到IDA中然后是这样: 发现上面有一串输出和我们命令行窗口中的一样,但是下面为什么又多了一大溜东 ...
- 把Android studio的日志导入目标文件中
最好是在Android studio的命令行工具中进行命令操作. adb logcat -v time > /Users/z/log.txt adb logcat -v time > /U ...