JVM

图来自JavaGuide
pPqDK1I.png

程序计数器

  • 程序计数器是线程私有的,每个线程一份,是线程安全的;
  • 内部保存的字节码的行号,用于记录正在执行的字节码指令的地址。

java堆

  • java堆是线程共享的区域(线程不安全),主要用来保存对象实例、数组等,内存不够会抛出OutOfMemoryError异常

  • 一个JVM只有一个堆内存,堆内存大小可以调节

  • 组成:年轻代+老年代

    • 年轻代分为三部分:Eden区和两个大小严格相同的Survivor区(8:1:1)
    • 老年代主要保存一些生命周期长的对象。
  • JDK1.7 和1.8 的区别

    • 1.7 堆中有一个永久代,存储类信息、静态变量、常量、编译后的代码,不存在垃圾回收,关闭虚拟机就会释放这个区域的内存
    • 1.8中堆中移除了永久代,把数据存储到了本地内存的元空间中,防止内存溢出。

字符串常量池的变化:

  • 1.6 在方法区
  • 1.7在堆区
  • 1.8 在元空间(1.8方法区变成了本地内存)

方法区是所有线程共享的内存,在java8以前是放在JVM内存中的,由永久代实现,受JVM内存大小参数的限制,在java8中移除了永久代的内容,方法区由元空间(Meta Space)实现,并直接放到了本地内存中,不受JVM参数的限制(当然,如果物理内存被占满了,方法区也会报OOM),并且将原来放在方法区的字符串常量池和静态变量都转移到了Java堆中。

所有的对象都是在Eden区new出来

OOM解决方法:

  • 扩大堆内存
  • 分析内存,看哪里出现问题

永久代逻辑上存在,物理上不存在

堆内存调优

-Xms 1m 设置初始化内存分配大小 默认本机内存1/64

-Xmx 1m 设置最大分配内存 默认本机内存1/4

-XX:+PrintGCDetails 打印GC垃圾回收信息

-XX:+HeapDumpOnOutOfMemoryError: 导出OOM异常文件

虚拟机栈

  • 每个线程运行时所需要的内存,称为虚拟机栈,先进后出
  • 每个栈由多个栈帧(frame)组成,对应着每次方法调用时所占的内存
  • 每个线程只能有一个活动栈帧,对应着当前正在执行的那个方法
  • 8大基本类型、对象引用、实例方法

正在执行的方法一定在栈的顶部

运行时栈帧包含的结构:局部变量表、操作数栈、动态连接、返回地址、附加信息

垃圾回收是否涉及栈内存

不涉及,垃圾回收主要指堆内存,当栈帧弹栈后,内存就会释放

栈内存分配越大越好吗?

  • 未必,默认栈内存1024k,栈帧过大会导致线程数变少

方法内的局部变量是否线程安全

  • 若方法内局部变量没有逃离方法的作用范围,它是线程安全的;
  • 若局部变量引用了对象并逃离方法的作用范围,需要考虑线程安全

什么情况下会导致堆内存溢出(StackOverflow)

  • 栈帧过多,典型问题:递归调用
  • 栈帧过大

堆、栈的区别

  • 栈内存一般用来存储局部变量和方法调用,堆内存用来存储java对象和数组。堆会GC垃圾回收,而栈不会。
  • 栈内存是线程私有的,堆内存是线程共有的
  • 两者异常错误不同,但如果栈内存或堆内存不足都会抛出异常。

方法区

  • 方法区是各个线程共享的内存区域
  • 主要存储静态变量、变量、类的信息、运行时常量池
  • 虚拟机启动的时候创建,关闭虚拟机时释放。
  • 若方法区中的内存无法满足分配请求,则会抛出OutOfMemoryError:Metaspace

运行时常量池

  • 常量池可以看做一张表,虚拟机指令根据这张表找到要执行的类名、方法名、参数类型等信息
  • 当类被加载时,它的常量池信息会放入运行时常量池,并将里面的符号地址变为真实地址。

直接内存

  • 直接内存并不属于JVM的内存结构,不由JVM进行管理。是虚拟机的系统内存。
  • 常见于NIO操作,用于数据缓冲区。读写性能高 ,不受JVM内存回收管理

GC垃圾回收

发生在堆。

垃圾回收算法

标记-清除算法

首先标记出所有不需要回收的对象,在标记完成后统一回收掉所有没有被标记的对象。

缺点:

  • 效率不高
  • 产生大量不连续的内存碎片
复制算法

内存分为大小相同的两块,每次使用其中的一块,当这一块的内存使用完后,就将还存活的对象复制到另一块去,然后再把使用的空间一次清理掉。

作用于新生代的Survivor区

缺点:

  • 可用内存变小,缩小为原来的一半
  • 不适用于老年代
标记整理算法

标记过程仍然与“标记-清除”算法一样,但后续步骤不是直接对可回收对象回收,而是让所有存活的对象向一端移动,然后直接清理掉端边界以外的内存。

根据老年代的特点提出的一种标记算法,多了整理这一步,因此效率也不高,适合老年代这种垃圾回收频率不是很高的场景。

分代收集算法

对象的生命周期不同,故根据对象的存货周期在堆中分为新生代、老年代,根据其特点选择合适的垃圾收集算法。

  • 新生代:标记-复制算法(每次收集都有大量对象死去,只需要付出少量对象的复制成本就可以完成垃圾清除)
  • 老年代:标记-清除或标记整理算法(对象存活几率高,要清除的少)

类的加载过程

pPqcw0P.png

主要分为七个过程

pPqg8H0.png

  1. 加载

    • 通过类名,获取二进制流,
    • 解析类的二进制数据流为方法区内的数据结构(Java类模型)
    • 创建java.lang.Class类的实例,作为方法区这个类的各种数据的访问入口
  2. 验证

    验证类是否符合JVM规范

  3. 准备

    为类变量分配内存并设置初始值

    • static变量是final的基本类型,以及字符串常量,值已确定,赋值在准备阶段完成

    • static变量,分配空间在准备阶段完成(设置默认值),赋值在初始化阶段完成

    • static变量是final的引用类型,那么赋值也会在初始化阶段完成

  4. 解析

    把类中的符号引用转变为直接引用

  5. 初始化

    对类的静态变量、静态代码块进行初始化操作

    • 从上到下
    • 优先初始化父类
  6. 使用

    JVM 开始从入口方法开始执行用户的程序代码

    • 调用静态类成员信息(比如:静态字段、静态方法)
    • 使用new关键字为其创建对象实例
  7. 卸载

    程序代码执行完毕后,JVM销毁Class对象,JVM也退出内存

双亲委派机制

当某个类加载器需要加载某个.class文件时,它首先把这个任务委托给他的上级类加载器,递归这个操作,如果上级的类加载器没有加载,下一级才会去加载这个类。

优点:

  • 避免某一个类被重复加载,保证唯一性。
  • 为了安全,保证类库API不会被修改

JVM调优

JVM调优主要是调整年轻代、老年代、元空间的内存大小及使用的垃圾回收器。

  • 设置堆内存的初始化、最大内存
-Xms : 设置堆的初始化内存大小
-Xmx :设置堆的最大内存大小
  • 设置年轻代中Eden区和Survivor区的大小比例(默认8:1:1)
-XXSurvivorRatio=3,表示年轻代中的分配比率survivor:survivor:eden = 1:1:3
  • 设置年轻代与老年代的大小比例(默认1:2)
-XX:newSize=n   设置年轻代的初始大小
-XX:MaxNewSize   设置年轻代的最大大小,  初始大小和最大大小两个值通常相同
  • 线程堆栈的设置

    默认1M,但128k就够用了

-Xss   对每个线程stack大小的调整,-Xss128k

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

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

相关文章

ECRS生产工时分析软件:工业效率提升的隐形引擎

降本增效往往是企业开工规划的第一步。那到底降什么本,增什么效呢,对于很多企业来说,都是从采购成本入手,结果采购成本是降下来了,但是整体品质却下降了。实际上,要降本增效,优化现场管理才是企…

leetcode 611. 有效三角形的个数(优质解法)

代码&#xff1a; class Solution {public int triangleNumber(int[] nums) {Arrays.sort(nums);int lengthnums.length;int n0; //三元组的个数//c 代表三角形最长的那条边for (int clength-1;c>2;c--){int left0;int rightc-1;while (left<right){if(nums[left]nums[r…

【JavaEE初阶】 HTTP响应报文

文章目录 &#x1f332;序言&#x1f38d;200 OK&#x1f340;404 Not Found&#x1f384;403 Forbidden&#x1f334;405 Method Not Allowed&#x1f38b;500 Internal Server Error&#x1f333;504 Gateway Timeout&#x1f332;302 Move temporarily&#x1f38d;301 Move…

序列号管理

序列号管理&#xff0c;将从以下方面进行学习和阐述 WHY 为什么需要序列号&#xff0c;有什么作用 HOW sap如何进行管理序列号 WHEN 什么情况下适合进行序列号管理 1、 什么是序列号 首先简单介绍一个序列号是什么东西&#xff0c;我们使用的手机、电脑或者大家…

Spring Framework远程代码执行漏洞 CVE-2022-22965 漏洞复现

Spring Framework远程代码执行漏洞 CVE-2022-22965 漏洞复现和相关利用工具 名称: Spring Framework 远程命令执行漏洞 描述: Spring core是Spring系列产品中用来负责发现、创建并处理bean之间的关系的一个工具包&#xff0c;是一个包含Spring框架基本的核心工具包&#xff0…

【SparkSQL】基础入门(重点:SparkSQL和Hive的异同、SparkSQL数据抽象)

【大家好&#xff0c;我是爱干饭的猿&#xff0c;本文重点介绍Spark SQL的定义、特点、发展历史、与hive的区别、数据抽象、SparkSession对象。 后续会继续分享其他重要知识点总结&#xff0c;如果喜欢这篇文章&#xff0c;点个赞&#x1f44d;&#xff0c;关注一下吧】 上一…

远程工具无法连接VMware虚拟机 (Network error: Connection timed out)

windowr输入&#xff1a;services.msc ①检查window相关的Vmmare服务是否开启&#xff1a; 确保上面这个几个启动类型是自动&#xff0c;状态是正在运行。 ②排查虚拟网卡是否禁用&#xff1a; 设置->网络->更改适配器选项&#xff1a; ③检查虚拟网络编辑器以及虚拟机…

Java数据结构之《栈实现括号匹配的检验》问题

一、前言&#xff1a; 这是怀化学院的&#xff1a;Java数据结构中的一道难度中等的一道编程题(此方法为博主自己研究&#xff0c;问题基本解决&#xff0c;若有bug欢迎下方评论提出意见&#xff0c;我会第一时间改进代码&#xff0c;谢谢&#xff01;) 后面其他编程题只要我写完…

QT 做一个登录,注册的跳转页面

思路&#xff1a; 1.登录需要判断账号与密码是否想等&#xff0c;相等才可跳转新页面&#xff0c;匹配失败输入框提示”账号密码不匹配”。 2.注册不需要判断&#xff0c;直接跳转新页面即可。 widget.cpp文件 #include "widget.h" #include "ui_widget.h&qu…

Linux-hid

/kernel/drivers/hid/hid-core.c hid总线驱动/kernel/drivers/hid/hid-generic.c hid通用驱动/kernel/drivers/hid/hid-multitouch.c 多点触控面板驱动/kernel/drivers/hid/hid-quirks.c hid-quirks.c 是 Linux 内核中的一个文件&#xff0c;用于实现 HID&#xff08;Human…

MySQL数据库相关面试题

MySQL 中的 varchar 和 char 有什么区别 在MySQL中&#xff0c;VARCHAR和CHAR都是用于存储字符串数据的数据类型&#xff0c;但它们有一些区别&#xff1a; 存储方式&#xff1a; CHAR是一种固定长度的字符类型&#xff0c;它会在存储数据时使用固定的长度&#xff0c;不足的…

CPU虚拟化的过程

VMCS 是Virtual Machine Control Structure。是 Intel 实现 CPU 虚拟化&#xff0c;记录 vCPU 状态的一个关键数据结构。VMCS 数据结构主要包含以下信息。 Guest-state area&#xff0c;即 vCPU 的状态信息&#xff0c;包括 vCPU 的基本运行环境&#xff0c;例如寄存器等。Hos…

4G5G防爆执法记录仪、防爆智能安全帽赋能智慧燃气,可视化巡检巡线,安全生产管控

随着燃气使用的普及&#xff0c;燃气安全问题日益突出。传统应急安全问题处理方式暴露出以下问题&#xff1a; 应急预案不完善&#xff1a;目前一些燃气企业的应急预案存在实用性不高、流程不清晰等问题&#xff0c;导致在紧急情况下难以迅速启动和有效执行。 部门协同不流畅…

融云 swift 自定义消息类型

有的时候 官方提供的消息类型并不能满足我们的需求&#xff0c;所以我们要定义消息类型 融云官方文档 一. 先创建一个类继承RCMessageContent class ChatRoomMessageContent: RCMessageContent { }二. 注册这个类 注意事项&#xff1a; 注册自定义消息代码必须在发送、接收该…

[Python入门系列之十二]安装Jupyter notebook与代码运行

引言 Jupyter Notebook将代码、图片和文本完美结合在一起&#xff0c;为编程学习带来了前所未有的便捷性。本文旨在为初学者提供一个关于Jupyter Notebook的入门指南。 什么是Jupyter Notebook Jupyter Notebook是一个开源的Web应用程序&#xff0c;允许你创建和共享包含代码…

【全栈开发】NextJS与RedwoodJS——哪个更好?

NextJS和RedwoodJS都是流行的基于JavaScript的web开发框架。开发人员很自然地希望在他们的项目中使用最好的工具、框架或库。 软件开发人员使用库或框架的主要原因是为了节省时间&#xff0c;避免重新发明轮子。库或框架是预先编写的代码片段&#xff0c;可以很容易地集成到开…

学习Java第57天,Servlet的基本使用步骤

步骤1 开发一个web类型的module 步骤2 开发一个UserServlet public class UserServlet extends HttpServlet {Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// 获取请求中的参数String usern…

wvp如果确认音频udp端口开放成功

用到工具 在服务器上开启端口监听 选中udp server&#xff0c;点击创建按钮 设置服务器监听端口 在客户端连接服务器端口 选中udp客户端&#xff0c;点击创建 输入服务器地址 远程端口和本地端口&#xff0c;本地端口只要没被占用都可以使用 &#xff0c;点击确认 发送数据 …

使用凌鲨管理本地git仓库

把本地git仓库添加到凌鲨后&#xff0c;可以更方便的获取git仓库的信息&#xff0c;比如查看commit记录&#xff0c;统计代码提交量&#xff0c;获取远程仓库的issue等功能。 功能 查看提交/分支/标记列表 查看提交差异 查看远程仓库和相关issue 每天代码量统计 添加本地仓库…

mapbox路径回放

路径回放 import * as turf from turf/turfexport default class RouteReplay {/**** param {*} map mapbox实例对象* param {*} routejson 路径geojson type lineString* param {*} nsteps nsteps type number* param {*} realRouteLayerId 线条realRouteLayerId type str…