JVM 之:Java 内存区域与内存溢出
内存区域
Java 虚拟机在执行 Java 程序的过程中会把他所管理的内存划分为若干个不同的数据区域。Java 虚拟机规范将 JVM 所管理的内存分为以下几个运行时数据区:程序计数器、Java 虚拟机栈、本地方法栈、Java 堆、方法区。
下图所示各数据区。

Java 虚拟机是基于栈的,而 Android 虚拟机是基于寄存器的。
基于栈的指令集最主要的优点是可移植性强,主要的缺点是执行速度相对会慢些;
而由于寄存器由硬件直接提供,所以基于寄存器指令集最主要的优点是执行速度快,主要的缺点是可移植性差。栈帧中方法返回地址
当一个方法被执行后,有两种方式退出该方法:执行引擎遇到了任意一个方法返回的字节码指令或遇到了异常,并且该异常没有在方法体内得到处理。
无论采用何种退出方式,在方法退出之后,都需要返回到方法被调用的位置,程序才能继续执行。方法返回时可能需要在栈帧中保存一些信息,用来帮助恢复它的上层方法的执行状态。
一般来说,方法正常退出时,调用者的 PC 计数器的值就可以作为返回地址,栈帧中很可能保存了这个计数器值,而方法异常退出时,返回地址是要通过异常处理器来确定的,栈帧中一般不会保存这部分信息。
方法退出的过程实际上等同于把当前栈帧出站,因此退出时可能执行的操作有:恢复上层方法的局部变量表和操作数栈,如果有返回值,则把它压入调用者栈帧的操作数栈中,调整 PC 计数器的值以指向方法调用指令后面的一条指令。Java 堆
Java Heap 是 Java 虚拟机所管理的内存中最大的一块,它是所有线程共享的一块内存区域。几乎所有的对象实例和数组都在这类分配内存。Java Heap 是垃圾收集器管理的主要区域,因此很多时候也被称为“GC堆”。
根据 Java 虚拟机规范的规定,Java 堆可以处在物理上不连续的内存空间中,只要逻辑上是连续的即可。如果在堆中没有内存可分配时,并且堆也无法扩展时,将会抛出 OutOfMemoryError 异常。内存溢出
下面给出个内存区域内存溢出的简单测试方法。

内存泄露和内存溢出的区别:
内存泄露是指分配出去的内存没有被回收回来,由于失去了对该内存区域的控制,因而造成了资源的浪费。Java 中一般不会产生内存泄露,因为有垃圾回收器自动回收垃圾,但这也不绝对,当我们 new 了对象,并保存了其引用,但是后面一直没用它,而垃圾回收器又不会去回收它,这边会造成内存泄露,
内存溢出是指程序所需要的内存超出了系统所能分配的内存(包括动态扩展)的上限。对象实例化分析
对内存分配情况分析最常见的示例便是对象实例化:
Object obj = new Object();
这段代码的执行会涉及 Java 栈、Java 堆、方法区三个最重要的内存区域。
假设该语句出现在方法体中,obj 会作为引用类型(reference)的数据保存在 Java 栈的本地变量表中,而会在 Java 堆中保存该引用的实例化对象。
Java 堆中还必须包含能查找到此对象类型数据的地址信息(如对象类型、父类、实现的接口、方法等),这些类型数据则保存在方法区中。
另外,由于 reference 类型在 Java 虚拟机规范里面只规定了一个指向对象的引用,并没有定义这个引用应该通过哪种方式去定位,以及访问到 Java 堆中的对象的具体位置,因此不同虚拟机实现的对象访问方式会有所不同,主流的访问方式有两种:使用句柄池和直接使用指针。
通过句柄池访问的方式如下:

通过直接指针访问的方式如下:

这两种对象的访问方式各有优势,使用句柄访问方式的最大好处就是 reference 中存放的是稳定的句柄地址,在对象被移动(垃圾收集时移动对象是非常普遍的行为)时只会改变句柄中的实例数据指针,而 reference 本身不需要修改。
使用直接指针访问方式的最大好处是速度快,它节省了一次指针定位的时间开销。目前 Java 默认使用的 HotSpot 虚拟机采用的便是是第二种方式进行对象访问的。
JVM 之:Java 内存区域与内存溢出的更多相关文章
- JVM内存区域与内存溢出异常
Java虚拟机在执行java程序时会把它所管理的内存会分为若干个不同的数据区域,不同的区域在内存不足时会抛出不同的异常. >>运行时数据区域的划分 (1)程序计数器程序计数器(Progra ...
- JVM基础知识(1)-JVM内存区域与内存溢出
JVM基础知识(1)-JVM内存区域与内存溢出 0. 目录 什么是JVM 运行时数据区域 HotSpot虚拟机对象探秘 OutOfMemoryError异常 1. 什么是JVM 1.1. 什么是JVM ...
- 深入理解jvm之内存区域与内存溢出
文章目录 1. Java内存区域与内存溢出异常 1.1. 运行时数据区域 1.1.1. 程序计数器 1.1.2. java虚拟机栈 1.1.3. 本地方法栈 1.1.4. Java堆(Java Hea ...
- 深入理解java虚拟机系列(一):java内存区域与内存溢出异常
文章主要是阅读<深入理解java虚拟机:JVM高级特性与最佳实践>第二章:Java内存区域与内存溢出异常 的一些笔记以及概括. 好了開始.假设有什么错误或者遗漏,欢迎指出. 一.概述 先上 ...
- 深入理解java虚拟机---->java内存区域与内存溢出异常
2. java内存区域于内存溢出异常 2.1 概述: 对于C/C++而言,内存管理具有最高的权利,既拥有每一个对象的“所有权”,又担负着每一个对象生命开始到结束的维护责任. 对于java而言,则把内存 ...
- 第二章Java内存区域与内存溢出异常
第二章 Java内存区域与内存溢出异常 一.概述 对与Java程序员来说,在虚拟机自动内存管理机制的帮助下,不再需要为每个new操作去写delete/free代码,不容易出现内存泄露和内存溢出问 题, ...
- 《深入理解java虚拟机》第二章 Java内存区域与内存溢出异常
第二章 Java内存区域与内存溢出异常 2.2 运行时数据区域
- 深入了解Java虚拟机(1)java内存区域与内存溢出异常
java内存区域与内存溢出异常 一.运行时数据区域 1.程序计数器:线程私有,用于存储当前所执行的指令位置 2.Java虚拟机栈:线程私有,描叙Java方法执行模型:执行方法时都会创建一个栈帧,存储局 ...
- 2.1 自动内存管理机制--Java内存区域与内存溢出异常
自动内存管理机制 第二章.Java内存区域与内存溢出异常 [虚拟机中内存如何划分,以及哪部分区域.什么样代码和操作会导致内存溢出.各区域内存溢出的原因] 一.运行时数据区域 Java虚拟机所管理的内存 ...
- 虚拟机--第二章java内存区域与内存溢出异常--(抄书)
这是本人阅读周志明老师的<深入理解Java虚拟机>第二版抄写的,有很多省略,不适合直接阅读,需要阅读请出门左转淘宝,右转京东,支持周老师(侵权请联系删除) 第二章java内存区域与内存溢出 ...
随机推荐
- ** exception error: no match of right hand side value
错误发生的情况是模式匹配失败.对于badmatch异常,很难找到单一的原因,但经常性的原因是你无意间尝试绑定已绑定过的变量.
- 快照库MV不能成功刷新问题的解决
前几天,一个用户找到我,说他们的物化视图不能刷新了,这得从几天前主库的一次意外down机说起(另文说明),前几天,用户现场的一个中心库因某原因意外down掉了,当时短期内对中心库进行了重启修复,没有造 ...
- darktrace 亮点是使用的无监督学习(贝叶斯网络、聚类、递归贝叶斯估计)发现未知威胁——使用无人监督 机器学习反而允许系统发现罕见的和以前看不见的威胁,这些威胁本身并不依赖 不完善的训练数据集。 学习正常数据,发现异常!
先说说他们的产品:企业免疫系统(基于异常发现来识别威胁) 可以看到是面向企业内部安全的! 优点整个网络拓扑的三维可视化企业威胁级别的实时全局概述智能地聚类异常泛频谱观测 - 高阶网络拓扑;特定群集,子 ...
- LSTM CNN GRU DGA比较
测试环境:linux,8cpu核,8G内存 优化后的模型比较 模型 速度/eps 准确率 NN ...
- java并发编程:线程安全管理类--原子操作类--AtomicLongFieldUpdater<T>
1.类 AtomicLongFieldUpdater<T> public abstract class AtomicLongFieldUpdater<T> extends Ob ...
- git commit steps(1)
git commit steps: if you are a new git user , you may need to set # git config --global user.email & ...
- 模拟QQ分组(具有伸缩功能) (添加开源框架的光闪烁效果)SimpleExpandableListAdapter 适配器的用法,并且可添加组及其组内数据。
package com.lixu.qqfenzu; import java.util.ArrayList; import java.util.HashMap; import java.util.Lis ...
- centos6:一个网卡上显示多个ip地址的错误
网卡显示如下: 上面显示em1有两个ip地址,其中36是设置的固定IP,212这个ip不清楚怎么搞出来的,但是通过212地址也能够正常连接主机.重启网卡之后,还是没有变化. 网卡em1配置如下,/e ...
- 解决WinForm(C#)中MDI子窗体最大化跑偏的问题
“用MDI方式打开一个子窗口体后,总是不能最大化显示,明明子窗口体的WindowState设置为Maximized?”,相信有很多人会遇到这的样问题,请按下面的方法设置即可使MDI子窗体最大化: 1. ...
- Vue.js 源码学习笔记 -- 分析前准备1 -- vue三大利器
主体 实例方法归类: 先看个作者推荐, 清晰易懂的 23232 简易编译器 重点: 最简单的订阅者模式 // Observer class Observer { constructor (d ...