java--JVM

news2025/7/20 21:10:06

JVM

  • 1.JVM的内存结构
  • 2.哪些部分会出现内存溢出
  • 3.方法区与永久代、元空间之间的关系
  • 4.JVM内存参数
  • 5.JVM垃圾回收算法
    • (1)标记清除
    • (2)标记整理
    • (3)标记复制
  • 6.GC和分代回收算法
  • 7.三色标记和并发漏标问题
  • 8.垃圾回收器
  • 9.什么情况下会造成内存溢出,怎么解决
  • 10.类加载过程、双亲委派
    • (1)类加载
    • (2)双亲委派
  • 11.对象的引用类型
    • (1)强引用
    • (2)软引用
    • (3)弱引用
    • (4)虚引用
  • 12.finalize的理解

1.JVM的内存结构

java源代码经过编译 ---> java字节码  ---> JVM 创建 main 主线程,使用的内存由虚拟机栈分配 --->
类加载子系统将类的原始信息加载到方法区 ---> 实例对象存储在堆中 ---> 局部变量和方法的参数存到虚拟机栈 --->
普通java方法的调用存在虚拟机栈 ---> 本地方法的调用存在本地方法栈 ---> 当前线程执行到第几行代码存在程序计数器中
---> 当对象不再使用,当内存不足时,会被垃圾回收回收

线程私有:程序计数器、虚拟机栈、本地方法栈
线程共享:方法区、堆

2.哪些部分会出现内存溢出

只有程序计数器不会出现内存溢出

(1)OutOfMemoryError的情况:
堆内存耗尽 -- 对象越来越多,又一直在使用,不能被垃圾回收
方法区内存耗尽 -- 加载的类越来越多,很多框架都会在运行期间动态产生新的类
虚拟机栈累积 -- 每个线程最多会占用1M内存,线程个数越来越多,而又长时间运行不销毁

(2)StackOverflowError
虚拟机栈内部 -- 方法调用次数过多

3.方法区与永久代、元空间之间的关系

(1)方法区是JVM规范中定义的一块内存区域,用来存储类元数据、方法字节码、即时编译器需要的信息等
(2)永久代是Hotspot虚拟机对JVM规范的实现(JDK1.8之前)
(3)元空间是Hotspot虚拟机对JVM规范的实现(JDK1.8之后),使用本地内存作为这些信息的存储空间

4.JVM内存参数

5.JVM垃圾回收算法

(1)标记清除

标记:
局部变量引用的对象和静态变量引用的对象都可以作为跟对象(GC Root),沿着跟对象的引用链,如果找到了某个对象,就加标记,
在垃圾回收时不会回收

清除:
没有加标记的对象直接释放内存

问题:被释放的内存不连续,会存在过多的内存碎片

(2)标记整理

标记:
局部变量引用的对象和静态变量引用的对象都可以作为跟对象(GC Root),沿着跟对象的引用链,如果找到了某个对象,就加标记,
在垃圾回收时不会回收

整理:
没有加标记的对象直接释放内存,将标记的对象移动到一端

问题:效率低,解决了内存碎片问题

常用于老年代(存活对象较多的区域)的垃圾回收

(3)标记复制

标记:
局部变量引用的对象和静态变量引用的对象都可以作为跟对象(GC Root),沿着跟对象的引用链,如果找到了某个对象,就加标记,
在垃圾回收时不会回收

复制:
将被标记的对象复制到另一个区域,将其他清除

问题:相比于标记整理效率提高了,但是占用了额外的内存

常用于新生代(存活对象较少的区域)的垃圾回收,不适用于老年代(存活对象多的区域)的垃圾回收

6.GC和分代回收算法

(1)GC

GC的目的是在于实现无用对象的内存自动释放,减少内存碎片、加快分配速度

GC要点:
(1)回收区域是堆内存,不包括虚拟机栈(在方法调用结束会自动释放方法占用的内存)
(2)判断无用对象,使用可达性分析算法,三色标记法标记存活对象,回收未标记对象
(3)GC的具体实现称为垃圾回收器
(4)GC大都采用了分代回收思想,理论依据是大部分对象朝生夕灭,用完立刻就可以回收,另有少部分对象会长时间存活,每次很难
回收,根据这两类对象的特性将回收区域分为新生代和老年代,不同区域应用不同的回收策略
(5)根据GC的规模可以分成 Minor GC(回收新生代),Mixed GC,Full GC(新生代和老年代都回收)

(2)分代回收

7.三色标记和并发漏标问题

(1)三色标记

(2)并发漏标

用户线程对垃圾回收线程的影响

解决漏标问题:
(1)Incremental Update
只要赋值发生,被赋值的对象就会被记录。最后对这些被记录的对象进行重新标记
(2)Snapshot At The Beginning,SATB
新加对象会被记录,
被删除引用关系的对象也会记录。最后对这些被记录的对象进行重新标记

8.垃圾回收器

(1)Parallel GC

伊甸园区内存不足发生 Minor GC,标记赋值 STW
老年代内存不足发生 Full GC,标记整理 STW
注重吞吐量

(2)ConcurrentMarkSweep GC

老年代并发标记,重新标记时需要STW,并发清除
Failback Full GC(清除速度不及需要创建新的速度时,开始老年代和新生代都释放)
注重响应时间

(3)G1 GC

响应时间与吞吐量兼顾
把堆内存划分成多个区域,每个区域都可以充当伊甸园区、幸存区、老年区

新生代回收:伊甸园区内存不足时,标记复制 STW,复制到幸存区
并发标记:老年代达到堆内存的45%会触发并发标记,老年代并发标记,重新标记时需要 STW
混合收集:并发标记完成,开始混合收集,参与复制的有伊甸园区、幸存区、老年代,其中老年代会根据暂停时间目标,选择部分
回收价值高的区域,复制时 STW
Failback Full GC

9.什么情况下会造成内存溢出,怎么解决

(1)误用固定大小线程池

它的工作队列可以放整数最大值数量的任务对象,任务对象占用的内存会导致内存溢出

使用线程池的时候,根据实际情况,定义有大小限制的任务队列

(2)误用带缓冲线程池

对最大救急线程数量没有限制,因此会造成内存溢出

自己控制最大救急线程数量

(3)查询数据量太大导致

注意不要一次性查询所有数据

(4)动态生成类过多导致内存溢出

10.类加载过程、双亲委派

(1)类加载

(1)加载
将类的字节码载入方法区,并创建类.class对象(在堆内存)
如果此类的父类没有加载,先加载父类
加载时是懒惰执行

(2)链接
验证--验证类是否符合Class规范,合法性、安全性检查
准备--为static变量分配空间,设置默认值
解析--将常量池的符号引用解析为直接引用

(3)初始化
执行静态代码块与非final静态变量的赋值
初始化是懒惰执行

final修饰的基本类型变量使用时不会进行类的加载,会将变量直接复制到自己的类中
final修饰的引用类型变量使用时会进行类的加载
class Student{
   static final int age=1;
   static final String name="lisi";
}
class test{
   System.out.printlf(student.age);//不会加载student类信息
   System.out.printlf(student.name);//会加载student类信息
}

(2)双亲委派

类加载器加载时的工作方式:优先委派上级类加载器进行加载,如果上级类加载器
   能找到这个类,由上级加载,加载后该类也对下级加载器可见
   找不到这个类,则下级类加载器才能有资格执行加载

目的:
让上级类加载器中的类对下级共享(反之不行),即能让你的类能依赖到jdk提供的核心类
让类的加载有优先次序,保证核心类先加载

11.对象的引用类型

(1)强引用

普通变量赋值即为强引用,如:Dog dog = new Dog();

通过 GC Root 的引用链,如果强引用找不到该对象,该对象才能被回收

(2)软引用

例如:SoftReference a = new SoftReference(new A());
如果仅有软引用该对象时,首次垃圾回收不会回收该对象,如果内存仍不足,再次回收时才会释放对象
软引用自身需要配合引用队列来释放
典型例子是反射数据

(3)弱引用

例如:WeakReference a = new WeakReference(new A());
如果仅有弱引用引用该对象,只要发生垃圾回收,就会释放该对象
弱引用自身需要配合引用队列来释放
典型例子是 ThreadLocalMap 中的 Entry 对象

(4)虚引用

例如:PhantomReference a = new PhantomReference(new A());
必须配合引用队列一起使用,当虚引用引用的对象被回收时,会将虚引用对象入队,由 Reference Handler 线程释放其关联的外部资源
典型例子:Cleaner 释放 DirectByteBuffer 占用的直接内存

12.finalize的理解

(1)它是Object中的一个方法,子类重写它,垃圾回收时此方法会被调用,可以在其中进行一些资源释放和清理工作
(2)但是将资源释放和清理放在finalize方法中不太好,非常影响性能,严重时甚至会引起OOM(内存溢出),从java9
开始就被标注为@Deprecated,不建议使用了

非常不好:
(1)FinalizerThread是守护线程,代码很有可能没来得及执行完,线程就结束了,造成资源没有正确释放
(2)会吞掉代码里的异常,导致不能判断在释放资源时是否出现错误
影响性能:
(1)重写了finalize方法的对象在第一次 GC 时,并不能及时释放它占用的内存,因为要等着FinalizerThread调用完
finalize,把它从第一个unfinalized队列移除后,第二次 GC 时才能真正的释放内存
(2)finalize的调用很慢,当内存不足时不能及时的释放内存,对象释放不及就会逐渐移入老年代,老年代对象积累过多就
会容易 full GC ,导致速度很慢。甚至 full GC 后如果释放的速度仍然跟不上创建新对象的速度,就会OOM(内存溢出)


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

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

相关文章

【分布式技术专题】「Zookeeper中间件」给大家学习一下Zookeeper的”开发伴侣”—Curator-Framework(基础篇)

CuratorFramework基本介绍 CuratorFramework是Netflix公司开源的一套Zookeeper客户端框架,它作为一款优秀的ZooKeeper客户端开源工具,主要提供了对客户端到服务的连接管理和连接重试机制,以及一些扩展功能,它解决了很多ZooKeeper…

Linux服务器配置与管理(基于Centos7.2)任务目标(四)

文章目录一、任务目标二、任务资讯三、任务实施3-1.RPM软件包管理3-2.YUM方式安装软件一、任务目标 实施该工单的任务目标如下: 知识目标 1.了解RPM提供的功能。 2.了解YUM相对于RPM所具有的优点。 能力目标 1.能够通过RPM安装及管理软件包。 2.能够通过YUM安装及管…

uni-app —— 小程序加入购物车实现过程

文章目录 前言一、示意图二、整体实现思路三、实现过程 1.加入购物车2.获取当前用户购物车信息3.解决数据获取不及时的问题总结前言 前文已经讲解了如何实现商品规格的选择,那么接下来就应该将用户选中的商品加入购物车啦!那么如何实现呢?请…

[附源码]计算机毕业设计JAVA儒家文化网站

[附源码]计算机毕业设计JAVA儒家文化网站 项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis M…

FilterListenerAjax的介绍

目录 一、Filter 1、Filter概述 2、过滤器链 二、Listener 三、Ajax 1、基本介绍 2、快速入门案例 3、axios 4、JSON 一、Filter 1、Filter概述 ▶ 过滤器 Filter 表示过滤器,是 JavaWeb 三大组件(Servlet、Filter、Listener)之一。过滤器可以把对资源的请…

Centos--基于Jdk1.8环境安装+卸载Jenkins

基础准备 本人选择的安装的环境基于jdk1.8 操作系统:Centos7.9 java: 1.8.0_262 检查是否有旧版本 $rpm -ql jenkins 如果有老版本可以卸载后,再执行后面的安装步骤 卸载 jenkins $rpm -e jenkins —删除遗留文件: $find / -iname jenkins | xa…

【Lilishop商城】No2-4.确定软件架构搭建三(本篇包括ES检索)

仅涉及后端,全部目录看顶部专栏,代码、文档、接口路径在: 【Lilishop商城】记录一下B2B2C商城系统学习笔记~_清晨敲代码的博客-CSDN博客 全篇只介绍重点架构逻辑,具体编写看源代码就行,读起来也不复杂~ 谨慎&#xff…

windows文本绘制 TextOut、DrawText、CreateFont、SetTextColor、SetBkColor、SetBkMode

文本绘制 TextOut-将文字绘制在指定坐标位置 DrawText-在矩形区域绘制字符串 int DrawText(HDC hdc, //DC句柄LPCSTR lpString, //字符串int nCount, //字符串长度LPRECT lpRect, //绘制文字的矩形框UINT uFormat //绘制的方式,重点,花样繁多的关键点 );绘制文字样…

持续集成和上传源码

1.测试左移,测试右移 2.持续集成 是指通过自动化的方式,频繁多次将代码集成到主干。 快速发现错误 每完成一点更新,就集成到主干,可以快速发现错误,定位错误也比较容易。 防止分支大幅偏离主干 如果不是经常集成&…

nginx源码分析--双端列表

1.基本数据结构 struct ngx_queue_s {ngx_queue_t *prev;ngx_queue_t *next; };结构成员: ngx_queue_t *prev;前驱指针 ngx_queue_t *next;后继指针 2.操作函数--头结点 2.1基本函数 define ngx_queue_init(q) \(…

七牛云 vue 图片上传简单解说,js 上传文件图片

七牛云 vue 图片上传简单解说,js 上传文件图片 一、七牛云简介 首次使用七牛云存储进行项目的图片存储,整了一上午才整明白,这些官方的教程把明白人也给说糊涂了,文档很不规范。 七牛云有免费的使用额度,https://ww…

[附源码]SSM计算机毕业设计汽车租赁管理系统-JAVA

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

Go学习之旅:包、变量和函数(DAY 1)

文章目录前引包、变量和函数1、包的概念和所用2、导出名或者导出函数3.1、函数参数声明方式(一)3.2、函数参数声明方式(二)4、函数返回值支持多值返回5、函数命名返回值6、变量声明7、变量的基础类型8、变量的默认值(零…

pytorch案例代码-3

双向循环神经网络 双向循环神经网络在RNN/LSTM/GRU里都有。比如RNN cell,只是把h0和x1传入做线性变换产生h1继续传入同一个cell做线性变换,线性变换的W和b共享,沿着这个方向就把所有隐层和最后的输出算出来了。 那么其中的每个结点&#xff0…

android-apk解包打包

title: android-apk解包打包 categories: Android tags: [android, 加壳] date: 2022-09-28 10:29:51 comments: false mathjax: true toc: true android-apk解包打包, 以下所有操作都需要在配置好 java 环境下进行 前篇 android apk解包和打包 - https://blog.csdn.net/u0114…

(十五)Spring之面向切面编程AOP

文章目录基础环境AOP介绍AOP的七大术语切点表达式Spring的AOP的使用环境准备基于AspectJ的AOP注解式开发通知类型前置通知Before后置通知AfterReturning环绕通知Around异常通知AfterThrowing最终通知After关于JoinPoint切面的先后顺序通用切点表达式全注解式开发AOP基于XML配置…

9、前端笔记-CSS-CSS三大特性

三大特性:层叠性、继承性、优先级 1、层叠性(覆盖性) 给相同的选择器设置相同的样式,此时一个样式会覆盖(层叠)其他冲突的样式。 层叠性原则: 同一选择器,样式冲突,遵…

【SpringBoot】MVC配置解决跨域但仍然存在跨域

文章目录1. 跨域问题出现与解决1. 跨域问题出现与解决 检查SpringBoot中的MVC配置。 public void addCorsMappings(CorsRegistry registry) {//允许跨域访问资源定义registry.addMapping("/**")//(只允许本地的指定端口访问)允许所有.allowedOrigins("*")…

数据结构之线性表中的单链表【详解】

文章目录前言:一、单链表1.单链表和顺序表的优缺点2.单链表的概念和学习3.单链表的各个接口的实现(详解每一步)3.1.先铺垫一下大致的思路3.2.然后这边我们看一下我们大致要实现的函数有哪些3.3.接下来我们就开始实现这些代码,并且…

用信号量实现进程同步与互斥(含代码分析)

信号量简单的来说就是一个变量,代表着系统中互斥资源的数量,通常用原语来实现对信号量机制的操作。 一对原语:wait(S)也称为P操作,singnal(S)也称为V操作。S表示信号量 对于wait原语本身的内部逻辑代码如下(这里以一…