深入理解jvm-2Edition-Java内存区域
1、运行时数据区域
Java虚拟机会将内存区域划分为几个区域,每个区域储存不同类型的数据或承担不同的功能。
PC,堆-Java堆,栈-虚拟机栈、本地方法栈,方法区、直接内存。
当类被实例化或static方法被调用时,Class文件被加载,关于类的信息储存在方法区里(有了模子)。虚拟机获得了类的相关信息,就可以在Java堆里创建实例对象了。类方法被调用时,便会在Java栈中产生一个栈帧来记录调用的上下文信息,其中局部变量表中保存了指向Java堆中实例对象的引用以便操纵对象。当程序的执行需要调用由其他语言编写的方法时(系统调用等的dll),就需要本地方法栈来服务。
1.1、程序计数器PC
下一条指令(字节码)的地址,通过改变PC的值来完成程序状态切换。多线程中,每个线程都有自己的执行流程,因此它们要有自己的程序计数器PC。
执行Native方法时,PC为空(Undefined)。
没有OutOfMemoryError。
1.2、Java虚拟机栈
描述Java方法的执行,线程私有,生命周期与线程相同。每个方法被调用时,都会在虚拟机栈中创建一个栈帧(Stack Frame),其中记录了方法执行的上下文信息(局部变量表、操作数栈、动态链 接、方法返回等)。通常所说的堆内存、栈内存一般指Java堆和虚拟机栈(局部变量表部分)。
局部变量表存放编译时确定的各种基本数据类型(boolea...、reference、returnAddress),局部变量表所需空间在编译时完成分配,运行期间不会改变。
栈深度超过最大值时-StackOverflowError;扩展时无法申请到足够内存-OutOfMemoryError。
1.3、本地方法栈
虚拟机栈为虚拟机运行Java方法(Java字节码)服务,而本地方法栈为虚拟机使用到的Native方法(本地方法)服务。
什么是本地方法?——"A native method is a Java method whose implementation is provided by non-java code."
Native Method就是一个java调用非java代码的接口。一个Native Method是这样一个java的方法:该方法的实现由非java语言实现,比如C。
StackOverflowError,OutOfMemoryError。
1.4、Java堆
存放类的实例对象,由所有线程共享。所有的对象实例以及数组都要在堆上分配(数组也是一种对象,不同类型数组会有不同的类)。
Java堆也是GC的主要管理区域,从垃圾回收角度看,Java堆可以细分为Young Generation(新生代)和Old Generation(老年代);
更加细分可以分为Eden空间、From Survivor空间和To Survivor空间等。划分的目的只是为了更好的进行垃圾回收。
逻辑地址连续,物理地址可不连续。
堆无法扩展时抛出OutOfMemoryError。
关于新生代、老年代、永久代更详细的介绍可参见:https://www.jianshu.com/p/d3a0b4e36c28
1.5、方法区
储存被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据,由所有线程共享。
常量池:Class文件一部分,存放编译期生成的各种字面量和符号引用。在类加载后存放入运行时常量池。
运行时常量池:方法区的一部分,相较于常量池更动态,运行期间也可能有新的常量放入。
1.6、直接内存
Direct Memory,不是虚拟机运行时数据区的一部分,也不是Java虚拟机规范中定义的内存区域。
NIO中使用的基于Channel和Buffer的IO方式可使用Native函数库直接分配堆外内存,然后通过一个存储在Java堆中的DirectByteBuffer对象操纵。避免了在Java堆和Native堆中来回复制,提高了性能。
1.7、HotSpot对象创建过程
1、new
2、在常量池中寻找符号引用
3、检查符号代表的类是否被加载、解析和初始化过,没有加载则进行加载,找不到Class文件则报ClassNotFind错误
4、为新生对象分配内存:
紧缩过的内存采用Bump the Point方式,即指针向空闲区域移动对象大小长度
内存没有紧缩过,不规整,则采用Free List方式,在记录的空闲块中寻找相应大小的块来分配
保证内存分配时的线程安全性:
1、采用同步处理,Compare And Set 加失败重试。
2、为每个线程预分配单独的空间,线程在其自己的空间上创建对象,但是,线程空间扩容时还是要进行同步处理。
5、将分配出的空间初始化为0(不包括对象头)
6、对对象头中信息进行必要设置
7、执行<init>进行对象初始化
1.8、对象内存布局
Header(对象头)、(Instance Data)实例数据、Padding(对其填充)。
Header分为两部分,第一部分存储对象的自身的运行时数据(HashCode、GC分代年龄、锁状态标记等);第二部分是类型指针,指向方法区中类的元数据信息。如果对象是一个数组,则还要有长度信息。
Instance Data部分存储对象的实例信息,包括它自己的以及继承而来的所有信息。存储顺序受虚拟机分配策略参数和字段在源码中定义顺序影响。
Padding只起占位符作用,受JVM对对象起始地址的要求影响。
1.9、对象访问定位
对象是在堆上创建的,而操作对象需要通过Java栈上的reference数据来进行。
主流方式有句柄和直接指针两种。
句柄池中的句柄保存了对象实例数据地址以及对象的类型数据(元数据)地址,reference中存储对象句柄的地址即可定位到对象和其元数据。
采用直接指针时,reference指向对象地址,对象的对象头中的类型指针指向其元数据地址。
句柄的优势是稳定,对象位置移动时,只需改动句柄中的数据,而reference本身不用改变。
直接指针直接指向对象,因此访问速度快。
1.10、内存区域相关的JVM参数
Xms20m 堆的最小值设为20m
Xmx20m 堆的最大值设为20m
XX:+HeapDumpOnOutOfMemoryError 让虚拟机在出现内存溢出时Dump出当前内存堆转储快照以便时候分析
Xss128k 设定栈容量为128k
Xoss128k 设置本地方法栈大小为128k(HotSpot不区分虚拟机栈和本地方法栈,因此该方法无用)
XX:MaxPermSize 设置方法区最大值
XX:PermSize 设置方法区大小
XX:MaxDirectMemorySize 设置最大直接内存大小,如不指定则与Java最大值一样
深入理解jvm-2Edition-Java内存区域的更多相关文章
- 理解JVM之Java内存区域
Java虚拟机运行时数据区分为以下几个部分: 方法区.虚拟机栈.本地方法栈.堆.程序计数器.如下图所示: 一.程序计数器 程序计数器可看作当前线程所执行的字节码行号指示器,字节码解释器工作时就是通过改 ...
- 深入理解JVM - 1 - Java内存区域划分
作者:梦工厂链接:https://www.jianshu.com/p/7ebbe102c1ae来源:简书简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处. Java与C++之间有一堵 ...
- 深入理解JVM(一)--Java 内存区域
一. 运行时数据区域 Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域. Java虚拟机所管理的内存将会包括以下几个运行时数据区域: ...
- 深入理解JVM(二)Java内存区域
2.1 C.C++内存管理是由开发人员管理,而Java则交给了JVM进行自动管理 2.2 JVM运行时数据区:方法区.堆(运行时线程共享),虚拟机栈.本地方法栈.程序计数器(运行时线程隔离,私有) 1 ...
- JVM之Java内存区域
JVM之Java内存区域 世界上并没有完美的程序,但我们并不因此而沮丧,因为写程序本来就是一个不断追求完美的过程. 一.JAVA内存区域 谈及JAVA虚拟机运行时数据区域就不得不祭出这张经典的图了: ...
- 学习jvm(一)--java内存区域
前言 通过学习深入理解java虚拟机的教程,以及自己在网上的查询的资料,做一个对jvm学习过程中的小总结. 本文章内容首先讲解java的内存分布区域,之后讲内存的分配原则以及内存的监控工具.再下来会着 ...
- 深入理解JVM(6)——Java内存模型和线程
Java虚拟机规范中定义了Java内存模型(Java Memory Model,JMM)用来屏蔽掉各种硬件和操作系统的内存访问差异,以实现让Java程序在各种平台下都能达到一致的内存访问效果(“即Ja ...
- 史上最详细JVM,Java内存区域讲解
本人免费整理了Java高级资料,一共30G,需要自己领取:传送门:https://mp.weixin.qq.com/s/JzddfH-7yNudmkjT0IRL8Q 运行时数据区域 JVM载执行Jav ...
- JVM:Java内存区域与内存溢出异常
Java 虚拟机在执行 Java 程序的过程中会把它所管理的内存划分为若干个不同的数据区域.这些区域都有各自的用途,以及创建和销毁时间,有些区域随着虚拟机进程的启动而存在,有些区域依赖用户线程的启动和 ...
- 深入理解虚拟机之Java内存区域
1 概述 对于Java程序员来说,在虚拟机自动内存管理机制下,不再需要像C/C++程序开发程序员这样为内一个new 操作去写对应的delete/free操作,不容易出现内存泄漏和内存溢出问题.正是因为 ...
随机推荐
- 使用VS调试时出现 :provider: Named Pipes Provider, error: 40 - 无法打开到 SQL Server 的连接 解决方案
首先检查链接的数据库名称是否正确 其二是看看你的主机名称由没有写对,有些写成 127.0.0.1会出错.我就是将sessionState中的127.0.0.1出错,改为自己的主机名称就OK啦
- js动态添加的html绑定事件
使用场景:网站上ul里面的li数据需要从后台数据查询出来即通过js添加数据.然后监听点击li点击事件. 添加数据代码: for(var i = 0; i < table.length; i++) ...
- WinUI桌面版替换UWP项目实际使用
最近做了一个3D打印的RC遥控车.然后就想着用xbox手柄控制小车的前进和转向吧,于是就用surface平板接收收手柄的数据,然后通过串口的2.4G模块传输数据,看上挺简单的,其实本身也挺简单的. 我 ...
- Spring到底应该学哪些内容?
大家好,我是冰河~~ 说实话,「Spring注解系列」这个专题的内容是去年开始更新的,期间,基本上已经更新完IOC容器相关的内容了.在即将更新AOP相关的内容时,由于种种原因吧,也有很多小伙伴在微信上 ...
- elk 日志收集 filebeat 集群搭建 php业务服务日志 nginx日志 json 7.12版本 ELK 解决方案
难的不是技术,难的是业务.熟悉业务流程才是最难的. 其实搜索进来的每一个人的需求不一样,希望你能从我的这篇文章里面收获到. 建议还是看官方文档,更全面一些. 一.背景 1,收集nginx acces ...
- 应用CRM的自动化功能为什么备受推崇
相信每个销售团队都遇到过这样的问题:在跟进新客户的时候顾此失彼,在跟踪一个客户的时候,转眼就忘记了另一个客户.这种情况很常见,但是每个新客户都有潜在的价值,我们该如何做,才能避免错失商机?CRM客户管 ...
- 学习vue遇到的第一个小怪兽:net::err_file_not_found
问题现象 引入vue.js文件时报错:net::err_file_not_found,我用的是VScode开发工具,调试工具用的Chrome. 解决方案 1.检查路径是否正确 2.检查文件是否有问题 ...
- XCTF_RE-Crc-300
这题讲道理其实还算简单的,还以为是啥算法呢..吓我一跳..拖入ida之后,发现逻辑还是挺清晰的 这个是关键函数,第一个if就可以求出后10个字符是啥了.. 接下就是对一个列表的赋值,然后就是一个dow ...
- 滑动窗口通用解leetcode字符串匹配问题
滑动窗口,这玩意解决一些字符串匹配的题目是真的挺好用的,虽然本质还是双指针. 思路: 1.维护一个窗口,不断的向右边移动 2.满足要求后,移动左边,当不满足时,跳出. 3.重复1,2.得出答案. 下面 ...
- Spring Boot 2.x基础教程:使用@Scheduled实现定时任务
我们在编写Spring Boot应用中经常会遇到这样的场景,比如:我需要定时地发送一些短信.邮件之类的操作,也可能会定时地检查和监控一些标志.参数等. 创建定时任务 在Spring Boot中编写定时 ...