JVM基础(内存结构)

文章目录

  • 内存结构
    • JAVA堆
    • 方法区 (Method Area)
      • 运行时常量池(Runtime Constant Pool)
    • 虚拟机栈 (Java Virtual Machine Stack)
    • 本地方法摘栈(Native Method Stacks)
    • 程序计数器(Program Counter Register)
    • 直接内存(Direct Memory)
  • JVM参数设置

内存结构

可称为java的自动内存管理机制。
在这里插入图片描述
三大部分:

  • 堆内存
  • 方法区
  • 栈内存

现在jdk默认使用的是 Hot-Spot 虚拟机。
在这里插入图片描述

JAVA堆

堆是虚拟机中最大的一块内存,被所有线程共享的内存区域.
唯一作用就是: 放New出来的对象,几乎所有对象都在这里面分配内存1(以后说不定)。

堆可以实现固定的大小也可以扩展(通过参数-Xmx和-Xms设定)扩展失败就会爆OOM异常

堆分两个区老年代和新生代 默认比例 young 1:2 oid 通过:–XX:NewRatio

新生代又分为Eden区和2个Survivor区(From Survivor 和 To Survivor)
默认的,Eden : from : to = 8 : 1 : 1
通过 –XX:SurvivorRatio来设定

深入理解java虚拟机:
Java 堆是垃圾收集器管理的内存区域,因此一些资料中它也被称作“GC堆”(Garbage Collected Heap,幸好国内没翻译成“垃圾堆”)。从回收内存的角度看,由于现代垃圾收集器大部分都是基于分代收集理论设计的,所以Java堆中经常会出现“新生代”“老年代”“永久代”“Eden空间”“From Survivor空间”“To Survivor空间”等名词,这些概念在本书后续章节中还会反复登场亮相,在这里笔者想先说明的是这些区域划分仅仅是一部分垃圾收集器的共同特性或者说设计风格而已,而非某个Java虚拟机具体实现的固有内存布局,更不是《Java虚拟机规范》里对Java堆的进一步细致划分。不少资料上经常写着类似于“Java虚拟机的堆内存分为新生代、老年代、永久代、Eden、Survivor……”这样的内容。在十年之前(以G1收集器的出现为分界),作为业界绝对主流的HotSpot虚拟机,它内部的垃圾收集器全部都基于“经典分代” 2来设计,需要新生代、老年代收集器搭配才能工作,在这种背景下,上述说法还算是不会产生太大歧义。

但是到了今天,垃圾收集器技术与十年前已不可同日而语,HotSpot里面也出现了不采 用分代设计的新垃圾收集器,再按照上面的提法就有很多需要商榷的地方了。

如果从分配内存的角度看,所有线程共享的Java堆中可以划分出多个线程私有的分 配缓冲区(Thread Local Allocation Buffer,TLAB),以提升对象分配时的效率。不过无 论从什么角度,无论如何划分,都不会改变Java堆中存储内容的共性,无论是哪个区 域,存储的都只能是对象的实例,将Java 堆细分的目的只是为了更好地回收内存,或 者更快地分配内存。在本章中,我们仅仅针对内存区域的作用进行讨论,Java堆中的上 述各个区域的分配、回收等细节将会是下一章的主题。

方法区 (Method Area)

jdk8之前又称永久代,同堆一样是一个线程共享的内存区域, 存储虚拟机加载的类信息、常量、静态变量,即时编译器编译后的代码缓存等数据。

深入理解java虚拟机:
虽然《Java虚拟机规范》中把方法区描述为堆的一个逻辑部分,但是它却有一个别名叫
作“非堆”(Non-Heap),目的是与Java堆区分开来。

JDK8之前的HotSpotJVM,存放这些”永久的”的区域叫做“永久代(permanent
generation)”。永久代是一片连续的堆空间,在JVM启动之前通过在命令行设
置参数-XX:MaxPermSize 来设定永久代最大可分配的内存空间,默认大小是64M
(64位JVM默认是85M)。

jdk8之后叫Metaspace(元空间)其实和之前的概念是一样的

从 Hotspot JVM 中删除永久代,因此需要调整永久代的大小。

Class metadata, interned Strings and class static variables will be moved from the permanent generation to either the Java heap or native memory.

The code for the permanent generation in the Hotspot JVM will be removed.
Application startup and footprint will not regress more than 1% as measured by a yet-to-be-chosen set of benchmarks.

运行时常量池(Runtime Constant Pool)

方法区的一部分
用于存放编译期生成的各种字面量与符号引用,这部分内容将在类加载后存放到方法区的运行时常量池中。
-会把由符号引用翻译出来的直接引用也存储在运行时常量池中。

运行时常量池没有格式上的细节规范,没一个虚拟机都可以自己实现这一个内存区域,相对于Class文件的常量池另一个特征是动态性,

Java语言并不要求常量一定只有编译期才能产生,也就是说,并非预置入Class文件中常量池的内容才能进入方法区运行时常量池,运行期间也可以将新的常量放入池中,这种特性被开发人员利用得比较多的便是String类的 intern()方法。

也会报oom异常

虚拟机栈 (Java Virtual Machine Stack)

常说的栈 内存就是这个玩意
线程私有

生命周期和线程一样

创建线程的时候也会创建虚拟机栈

java程序执行时,每一个方法都会 创建 一个栈帧 放到虚拟机栈中 通过压栈出栈的方式进行方法调用

栈帧又分为一下几个区域:局部变量表、操作数栈、动态连接、方法出口等

我们所说的变量存在栈中,这句话说的不太严谨,应该说局部变量存放在java 虚拟机栈的局部变量表中。
java 的8中基本类型的局部变量的值存放在虚拟机栈的局部变量表中,如果是引用型的变量,则只存储对象的引用地址。

局部变量表存放了编译期可知的各种Java虚拟机基本数据类型(boolean、byte、
char、short、int、 float、long、double)、对象引用(reference类型,它并不等同于对象
本身,可能是一个指向对象起始地址的引用指针,也可能是指向一个代表对象的句柄或
者其他与此对象相关的位置)和returnAddress 类型(指向了一条字节码指令的地址)。

这些数据类型在存储空间以局部变量槽(Slot)来表示,64位长度的long和double占两个Slot,
其余占一个
局部变量的内存空间在 编译期间产生并分配

经常有人把Java内存区域笼统地划分为堆内存(Heap)和栈内存(Stack),这种划
分方式直接继承自传统的C、C++程序的内存布局结构,在Java语言里就显得有些粗糙
了,实际的内存区域划分要比这更复杂。

可能出现的异常就是OutOfMemoryError ,如果可以动态扩展,但是还是不够就会报OutOfMemoryError

本地方法摘栈(Native Method Stacks)

与虚拟机栈的作用是非常相似的

  • 区别不过是虚拟机栈为虚拟机执行Java方法(也就是字节码)服务
  • 而本地方法栈则是为虚拟机使用到的Native方法服务。

《Java虚拟机规范》对本地方法栈中方法使用的语言、使用方式与数据结构并没有任何强制规定,因此具体的虚拟机可以根据需要自由实现它,甚至有的Java虚拟机(譬如Hot-Spot虚拟机)直接就把本地方法栈和虚拟机栈合二为一。与虚拟机栈一样,本地方法栈也会在栈深度溢出或者栈扩展失败时分别抛出StackOverflowError和OutOfMemoryError 异常。

程序计数器(Program Counter Register)

在虚拟机的概念模型中计数器: 记录当前线程执行程序的位置,改变计数器的值来确定执行的下一条指令,
比如循环、分支、方法跳转、异常处理,线程恢复都是依赖程序计数器来完成。

Java 虚拟机多线程是通过线程轮流切换并分配处理器执行时间的方式实现的。

为了线程切换能恢复到正确的位置,每条线程都需要一个独立的程序计数器,所以它是线程私有的。(在任何一个确定的时刻,处理器的一个内核中只会执行一个线程的指令,)

如果线程正在执行的是一个Java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址;
如果正在执行的是Native方法,这个计数器值则为空(Undefined)。
此内存区域是唯一一个在Java虚拟机规范中没有规定任何OutOfMemoryError(内存溢出)情况的区域。

直接内存(Direct Memory)

这个不是虚拟机的内存,但是也会检查使用而且还会报oom异常

在JDK 1.4中新加入了NIO(New Input/Output)类,引入了一种基于通道(Channel)与缓冲区(Buffer)的I/O方式,它可以使用Native函数库直接分配堆外内存,然后通过一个存储在Java堆里面的 DirectByteBuffer对象作为这块内存的引用进行操作。这样能在一些场景中显著提高性能,因为避免了在Java堆和Native堆中来回复制数据。

这个内存不受java堆的限制,但受物理主机限制
这个动态控制需求大于你实际物理主机的情况下肯定会报oom了,

显然,本机直接内存的分配不会受到Java堆大小的限制,但是,既然是内存,则肯
定还是会受到本机总内存(包括物理内存、SWAP分区或者分页文件)大小以及处理器
寻址空间的限制,一般服务器管理员配置虚拟机参数时,会根据实际内存去设置-Xmx
等参数信息,但经常忽略掉直接内存,使得各个内存区域总和大于物理内存限制(包括
物理的和操作系统级的限制),从而导致动态扩展时出现OutOfMemoryError异常。

JVM参数设置

  • -Xms设置堆的最小空间大小。
  • -Xmx设置堆的最大空间大小。
  • -Xmn:设置年轻代大小
  • -XX:NewSize 设置新生代最小空间大小。
  • -XX:MaxNewSize 设置新生代最大空间大小。
  • -XX:PermSize 设置永久代最小空间大小。
  • -XX:MaxPermSize 设置永久代最大空间大小。
  • -Xss设置每个线程的堆栈大小
  • -XX:+UseParallelGC:选择垃圾收集器为并行收集器。此配置仅对年轻代有效。即上述配置下,年轻代使用并发收集,而年老代仍旧使用串行收集。
  • -XX:ParallelGCThreads=20:配置并行收集器的线程数,即:同时多少个线程一起进行垃圾回收。此值最好配置与处理器数目相等。

Xmx3550m:设置 JVM 最大可用内存为3550M。
-Xms3550m:设置 JVM 促使内存为3550m。此值可以设置与-Xmx相同,以避免每次垃圾回收完成后JVM重新分配内存。
-Xmn2g:设置年轻代大小为2G。整个堆大小=年轻代大小+年老代大小+持久代大小。
持久代一般固定大小为64m,所以增大年轻代后,将会减小年老代大小。此值
对系统性能影响较大,官方推荐配置为整个堆的3/8。-Xss128k:设置每个线程的堆栈大小。JDK5.0以后每个线程堆栈大小为1M,以前
每个线程堆栈大小为256K。更具应用的线程所需内存大小进行调整。在相同物理内存下,减小这个值能生成更多的线程。但是操作系统
对一个进程内的线程数还是有限制的,不能无限生成,经验值在3000~5000
左右。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/57097.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Matlab 车牌识别技术

1.1设计内容及要求: 课题研究的主要内容是对数码相机拍摄的车牌,进行基于数字图像处理技术的车牌定位技术和车牌字符分割技术的研究与开发,涉及到图像预处理、车牌定位、倾斜校正、字符分割等方面的知识,总流程图如图1-1所示。 图1-1系统总…

智慧共享空间解决方案是什么

一、智慧共享空间解决方案的定义 智慧共享空间解决方案是一种综合性的策略和技术手段,旨在通过整合智慧技术与共享空间的概念,为公众共同使用的空间提供高效、智能、可持续的运营和管理模式,以满足人们在不同环境下的各种需求,并…

C++基于opencv的视频质量检测--画面冻结检测

文章目录 0.引言1. 原始代码分析2. 优化方案3. 优化后的代码4. 代码详细解读 0.引言 视频质量画面冻结检测已在C基于opencv4的视频质量检测中有所介绍,本文将详细介绍其优化版本。 1. 原始代码分析 图像抖动检测的原始代码: bool ScreenFreezeDetect…

AI驱动的低代码未来:加速应用开发的智能解决方案

引言 随着数字化转型的浪潮席卷全球,企业对快速构建应用程序的需求愈发强烈。然而,传统的软件开发周期冗长、成本高昂,往往无法满足快速变化的市场需求。在此背景下,低代码平台逐渐成为开发者和企业的优选方案,以其“低…

【蓝桥杯选拔赛真题77】python计算小球 第十五届青少年组蓝桥杯python选拔赛真题 算法思维真题解析

目录 python计算小球 一、题目要求 1、编程实现 2、输入输出 二、算法分析 三、程序编写 四、程序说明 五、运行结果 六、考点分析 七、 推荐资料 1、蓝桥杯比赛 2、考级资料 3、其它资料 python计算小球 第十五届蓝桥杯青少年组python比赛选拔赛真题 一、题目要…

架构师备考-非关系型数据库

基础理论 CAP 理论 C(Consistency)一致性。一致性是指更新操作成功并返回客户端完成后,所有的节点在同一时间的数据完全一致,与ACID 的 C 完全不同。A (Availability)可用性。可用性是指服务一直可用&…

内网渗透-初探域渗透

文章目录 环境域信息收集系统基本信息网络信息域控主机信息根据ip查主机名用户信息权限提升网络探针系统命令nbtscanfscannishang 凭据收集 域渗透实战凭据收集(重点)mimikatzProcdumpPwdumpSAMInsidekrbtgt用户hash hash破解解决无法获取明文的问题明文口令传递IPC连接atschta…

windows录屏软件工具推荐!!

如今,科技的进步,互联网的普及,使我们的生活越来越便利,录屏工具的出现,大大提高我们的工作效率。如果你经常需要录制屏幕上的内容,比如制作教学视频、游戏实况记录、演示文稿等等,那这几款软件…

【病毒分析】从无解到破解:Mallox家族linux版本的分析以及解密器的制作

1.背景 Mallox勒索软件首次出现于2021年5月,并在2021年10月扩展到中国市场。截至2024年,它仍然活跃。Mallox通过加密受害者文件并要求支付赎金来恢复数据,使用唯一的加密密钥加密文件,受害者的文件通常会添加“.mallox”或“.mal…

【LeetCode每日一题】——862.和至少为 K 的最短子数组

文章目录 一【题目类别】二【题目难度】三【题目编号】四【题目描述】五【题目示例】六【题目提示】七【解题思路】八【时空频度】九【代码实现】十【提交结果】 一【题目类别】 前缀和 二【题目难度】 困难 三【题目编号】 862.和至少为 K 的最短子数组 四【题目描述】 …

容器化核心快速入门

概述 物理机:好比是独立的大船,独立发动机,独立船舱。所有资源共用。运水果的同时就不能运鱼( 1964年)虚拟机:相当于把大船进行改造,把大船的资源进行独立的拆分,独立的部分都有单独…

适合自己的才行-这五款项目管理软件工具帮你提高管理效能

凭借多年项目管理经验,我试用过数十款国内外项目管理软件。我认为,操作简便性至关重要,因为软件仅是辅助管理工具,复杂性若影响管理本质,则得不偿失。 在生产管理方面,我专注于新产品从立项到研发的全过程…

【网络原理】HTTPS

目录 前言 为什么要使用HTTPS? HTTPS是如果进行加密的 1.对称加密 2.非对称加密 中间人攻击 3.证书 中间人有没有可能篡改证书? 中间人有没有可能整个调包证书? 前言 在上一篇中,我们讲解了什么是HTTP,但是在…

现代数字信号处理I--最佳线性无偏估计 BLUE 学习笔记

目录 1. 最佳线性无偏估计的由来 2. 简单线性模型下一维参数的BLUE 3. 一般线性模型下一维参数的BLUE 4. 一般线性模型下多维参数的BLUE 4.1 以一维情况说明Rao论文中的结论 4.2 矢量参数是MVUE的本质是矢量参数中的每个一维参数都是MVUE 4.3 一般线性模型多维参数BLUE的…

[简易版] 自动化脚本

前言 uniapp cli项目中没办法自动化打开微信开发者工具,需要手动打开比较繁琐,故此自动化脚本就诞生啦~ 实现 const spawn require("cross-spawn"); const chalk require("picocolors"); const dayjs require("dayjs&quo…

牛客网刷题(1)(java之数据类型、数组的创建(静态/动态初始化)、static关键字与静态属性和方法、常用的servlet包、面向对象程序设计方法优点)

目录 一、Java变量的数据类型。 <1>Java中变量的数据类型。 <2>基本数据类型。 <3>引用数据类型。 二、Java中一维数组的初始化。&#xff08;静态、动态初始化&#xff09; <1>数组。 <2>动态初始化。 <3>静态初始化。 三、看清代码后&am…

Cesium基础-(Entity)-(Billboard)

里边包含Vue、React框架代码 2、Billboard 广告牌 Cesium中的Billboard是一种用于在3D场景中添加图像标签的简单方式。Billboard提供了一种方法来显示定向的2D图像,这些图像通常用于表示简单的标记、符号或图标。以下是对Billboard的详细解读: 1. Billboard的定义和特性 B…

模型训练识别手写数字(一)

一、模型训练数据集 1. 导入所需库 import numpy as np from sklearn.datasets import fetch_openmlnumpy 是用于数值计算的库。 fetch_openml 是用于从 OpenML 下载数据集的函数。 2. 获取 MNIST 数据集 X, y fetch_openml(mnist_784, version1, return_X_yTrue)fetch_ope…

LeetCode算法(双指针)

今天的题目主要都是力扣前100中&#xff0c;关于双指针的题 1.移动零 链接&#xff1a;移动零 示例&#xff1a; 示例 : 输入: nums [0,1,0,3,12] 输出&#xff1a;[1,3,12,0,0] 可以看到保持原有元素的顺序&#xff0c;将所有的0&#xff0c;移动到数组最后方即可。 这…

开源项目工具:LeanTween - 为Unity 3D打造的高效缓动引擎详解(比较麻烦的API版)

1.LeanTween.reset() 一、工具介绍 参考&#xff1a;推荐开源项目&#xff1a;LeanTween - 为Unity 3D打造的高效缓动引擎-CSDN博客 LeanTween是一个专为Unity 3D引擎设计的高效缓动&#xff08;tweening&#xff09;库&#xff0c;它提供了简单易用的API&#xff0c;帮助开…