Java内存模型,全称Java Memory Model(JMM)。
我们都知道创建一个对象需要分配内存空间并且在不需要该对象时及时回收内存。仔细回想,我们似乎并没有为我们new创建的每一个对象来编写过分配内存空间及回收内存相应的代码。但对象仍然很好的被回收了,原因是Java程序将内存的控制权交给了JVM虚拟机,所以在不了解虚拟机的内存机制的情况下,如果出现了内存泄漏与溢出,那么排查错误将是一个非常艰巨的任务。
要想知道JVM如何规划内存,首先要知道数据在内存中如何储存,当然不同类型的数据在内存中所存储的区域也不同。那么我们先带大家了解一下不同数据在内存中所储存的相应位置。
JVM在执行Java程序时会将它管理的内存划分为不同的数据区域。而这些区域在JDK1.8前后又有所变化。
线程共享 | Heap堆区、Method Area方法区 |
线程私有 | 程序计数器、虚拟机栈、本地方法栈 |
JDK1.8后:
线程私有 | Heap堆区、MetaSpace元空间 |
线程私有 | 程序计数器、虚拟机栈、本地方法栈 |
程序计数器是用于存放下一条指令所在单元的地址的地方。每执行一条指令,程序计数器就会加一。每个线程都会维护一个独立的程序计数器且各线程之间的程序计数器互不影响,在程序执行过程中,线程会不断的切换,独立的线程计数器保证了当前线程的正确执行位置。程序计数器是唯一一个不会出现OutOfMemoryError的内存区域,它随着线程的创建而创建,随着线程的结束而消亡。
Java虚拟机栈是线程私有的,它是由许多栈帧组成,而每个栈帧又包括了局部变量表、操作数栈、动态链接以及方法出口信息。每次方法调用都会将对应的栈帧压入虚拟机栈,当方法调用结束(方法调用return或者方法抛出异常)又会将该栈帧从虚拟机栈中弹出。由于栈的特性(FILO),每次操作的都是栈顶栈帧,又被称为“当前活动栈帧”,代表当前正在执行的方法。在JVM执行引擎运行时,所有指令都针对于当前活动栈帧进行操作。
Java虚拟机栈会出现的错误:
StackOverFlowError | jvm规定了虚拟机栈的最大深度,当执行当前线程时栈帧压入的深度大于了规定的深度,就会抛出该错误,一般是由于递归导致的无限嵌套调用递归方法。 |
OutOfMemoryError | JVM的内存大小可以动态扩展,如果虚拟机在扩展栈时无法申请到足够的内存空间,就会抛出该错误。 |
native关键字修饰的方法被称为本地方法,当线程调用本地方法时,会在本地方法栈中压入当前本地方法的栈帧。该栈帧中包含本地方法的局部变量表、操作数栈、动态链接、方法出口信息。当方法执行完毕时,栈帧会从本地方法栈中弹出,与虚拟机栈相同也会出现StackOverFlowError与OutOfMemoryError错误。
堆区是JVM所管理的内存中最大的一块区域,该区域被所有线程共享,堆区用于存放了大部分对象实例以及数组,随着 JIT编译器的发展与逃逸分析技术逐渐成熟,栈上分配、标量替换优化技术将会导致一些微妙的变化,从 JDK 1.7 开始已经默认开启逃逸分析,如果某些方法中的对象引用没有被返回或者未被外面使用(未逃逸出去),那么这部分对象可以直接在栈上分配内存。
Heap堆区又分为新生代和老年代,Heap堆区是垃圾收集器GC管理的主要区域。从垃圾回收的角度来看,垃圾收集器基本采用分代收集垃圾的思想,所有JVM的堆区往往采用分代划分的思想。
分代划分目的:更好的回收与分配内存
元空间是用于存放类信息、常量、静态变量、JIT即时编译器编译后的机器代码等数据。在JDK1.6时,HotSpot JVM采用Method Area方法区来储存这些数据,也叫永久代(持久代)。
方法区与永久代(持久代)的区别:
JDK1.7时将字符串常量池、静态变量转移到了堆区
JDK1.8时采用MetaSpace代替了永久代(持久代)
元空间与永久代(持久代):
相同点 | 都是对JVM规范方法区的一种实现 |
不同点 | 永久代(持久代)在虚拟机中,元空间在本地内存 |
永久代(持久代)内存受永久代(持久代)的GC与老年代的内存空间限制,元空间大小受本地内存限制 |
Java8后HotSpot JVM为什么要删除永久代(持久代)?
- 由于永久代(持久代)内存受限范围较小,经常会发生内存溢出
- 由于JRockit VM没有永久代(持久代),移除HotSpot JVM的永久代(持久代)可以促进HotSpot JVM与JRockit VM的融合
文章浏览阅读5k次,点赞7次,收藏24次。话不多说,开局一张图,内容全靠“编”:播放透明视频_wlmedia
文章浏览阅读4.5k次,点赞3次,收藏3次。Python从入门到精通零基础入门篇
文章浏览阅读101次。matplotlib部分:1.windows下设置字体:my_font=font_manager.FontProperties(fname=‘C:\Windows\Fonts\simsun.ttc’)2.plt.xlabel()设置x轴意义 plt.ylabel()设置y轴意义3.plt.xticks()设置x轴坐标 plt.yticks()设置y轴坐标Course exercises:4.折线图:plt.plot()5.散点图:plt.scatter()6.绘制网格:plt.grid()7_深度学习中的常用的统计图
文章浏览阅读2.4k次。surface_normals_object_model_3d( : : ObjectModel3D, Method, GenParamName, GenParamValue : ObjectModel3DNormals)计算三维物体模型的三维曲面法线输入:ObjectModel3D (input_control)包含3D点数据的3D对象模型句柄。Method(input_contr..._surface_normals_object_model_3d
文章浏览阅读8.1k次,点赞12次,收藏61次。目录仿真目标1、创建如下所示布局2、创建变量3、添加光纤段4、查看3D结构5、检查折射率分布6、选择激励场7、添加Pathway和Pathway Monitor8、执行仿真并选择输出种类9、访问保存的数据仿真目标布局和仿真沿着光纤在1.55μm处模式的传输,其包层折射率为1.49,纤芯折射率为1.5,芯子直径为9μm。1、创建如下所......_rsoft
文章浏览阅读3.8k次。本文转载自云期刊,原文地址:https://www.yunqikan.cn/2246.html云服务器具有维护成本低,安全稳定,高可扩展性和 7 X 24 小时的售后支持的优势,因此云服务器成为中小企业建站的首要选择。国内的云服务器竞争也进入了跑马圈地的时代,以阿里云、腾讯云、百度云三大BAT为首,不断推出优惠活动,争取更多的用户体量;以华为云、天翼云、西部数据为代表的云产品服务商紧跟其后,谁也...
文章浏览阅读1.5k次。_软件测试什么是交互缺陷
文章浏览阅读8.8k次。我们有时候会遇到这种业务场景: 进入某个页面时,我们需要验证用户是否已经登陆,是否拥有足够权限?我们可以通过监听路由的变化来实现。但是在react下,怎么实现呢?下面讨论实现过程:手动实现react-router-watcher实现手动实现使用Hook方式实现:import { useEffect, useState, useRef, useCallback, useMemo } from 'react'import { useLocation, useHistory, useRouteM_react监听路由变化
文章浏览阅读707次。Redis主从复制主机数据更新后根据配置和策略,自动同步到备机的master/slaver机制,master以写为主,slaver以读为主,特点:读写分离,性能扩展,缓解访问压力。容灾快速恢复,从服务器挂掉了,可以转换到另外的从服务器。一主多从,只能有一台主服务器,老大只能有一个,问从服务器挂了可以切换,主机挂了呢?可以配置一个集群,一台主机多个从机,一个主机挂掉换另一个主机。怎么玩?怎么配置?1.创建一个/myredis文件夹mkdir /myredis2.复制redis.co_如何给redis创建文件夹
文章浏览阅读6.7k次,点赞2次,收藏17次。介绍Delegate 代理类被用来显示和编辑Item项。为了能实现自定义的Item,需要子类化代理类,并实现自己的paint() 和 sizeHint()方法。paint()方法会被每个Item调用,来绘制自定义的样式和相应的数据类型,sizeHint()方法用于指示每个Item的大小。在重绘Item在View中的显示时,QStyle类提供了很多的细节样式。在Qt4.4以后,有两个代理类QIte_qt自定义item
文章浏览阅读1.7k次,点赞3次,收藏10次。一文快速了解分布式版本控制系统Git_软件版本控制系统的运行结果图
文章浏览阅读5.1w次,点赞133次,收藏1.3k次。IDEA使用教程下载安装IntelliJ IDEA 介绍IDEA,全称 IntelliJ IDEA,是 Java 语言的集成开发环境,IDEA 在业界被公认为是最好的 java 开发工具之一,尤其在智能代码助手、代码自动提示、重构、J2EE 支持、Ant、JUnit、CVS 整合、代码审查、创新的 GUI 设计等方面的功能可以说是超常的。IntelliJ IDEA 在官网上这样介绍自己:Excel at enterprise, mobile and web development with Jav_java idea