内存问题(一)——内存概述

news2024/11/25 16:44:42

一、内存泄漏(Memory Leak)

  是指程序中已动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果。

二、一般内存泄露的方式

  1. 常发性内存泄漏:发生内存泄漏的代码会被多次执行到,每次被执行时都会导致一块内存泄漏;
  2. 偶发性内存泄漏:发生内存泄漏的代码只有在某些特定环境或操作过程下才会发生。常发性和偶发性是相对的。对于特定的环境,偶发性的也许就变成了常发性的。所以测试环境和测试方法对检测内存泄漏至关重要;
  3. 一次性内存泄漏:发生内存泄漏的代码只会被执行一次,或者由于算法上的缺陷,导致总会有一块且仅有一块内存发生泄漏;
  4. 隐式内存泄漏:程序在运行过程中不停的分配内存,但是直到结束的时候才释放内存。严格的说这里并没有发生内存泄漏,因为最终程序释放了所有申请的内存。但是对于一个服务器程序,需要运行几天,几周甚至几个月,不及时释放内存也可能导致最终耗尽系统的所有内存。所以,我们称这类内存泄漏为隐式内存泄漏。从用户使用程序的角度来看,内存泄漏本身不会产生什么危害,作为一般的用户,根本感觉不到内存泄漏的存在。真正有危害的是内存泄漏的堆积,这会最终耗尽系统所有的内存。从这个角度来说,一次性内存泄漏并没有什么危害,因为它不会堆积,而隐式内存泄漏危害性则非常大,因为较之于常发性和偶发性内存泄漏它更难被检测到;

三、JAVA中的内存泄露

  上面所描述的是通常的内存泄露方式,当然也适用于java,但是对于java而言,问题似乎变得简单了,JAVA的一个重要特性就是通过垃圾收集器(GC)自动管理内存的回收,而不需要程序员自己来释放内存。理论上Java中所有不会再被利用的对象所占用的内存,都可以被GC回收,但是Java也存在内存泄露,但它的表现与C或者C++不同而已。这通常都是设计不合理造成的,也因此通过设计是可以避免的。根本问题在于,是否我们需要掌控的对象,在应该销毁的时候没有销毁,或者没有预料到对象的增量超出我们的预想。

  • 对象增长超出预想;
  • 设计应该销毁的对象,而常驻内存;

  对于问题一,举一个常见的设计规约:线程池的创建应该显示指定阻塞队列得到小,避免默认值失去控制,极坏的情况下创建了大量的线程,导致OOM。
  问题二,经常出现在设计缓存,存储的map,list中,无限增长,失去控制。

四、常见的容易导致内存泄露的点

  1. 线程池创建未显示指定阻塞队列大小;
  2. ThreadLocal 的管理中忘记回收对象;
objectThreadLocal.set(userInfo);
try {
// ...
} finally {
objectThreadLocal.remove();
}
  1. 所有涉及资源链接的地方,都不要忘记关闭资源;
  2. 类的成员变量为集合,或者单例的模式中有集合,引用了大量的其他对象;
  3. java方法,是传值还是传引用,造成的小时间段内,内存没按照预想回收掉;

五、内存溢出(Out Of Memory)

  内存溢出就是内存越界。内存越界有一种很常见的情况是调用栈溢出(即stackoverflow),虽然这种情况可以看成是栈内存不足的一种体现。

六、内存溢出跟内存泄露区别

  • 内存溢出:申请内存时,JVM没有足够的内存空间;
  • 内存泄露:申请了内存,但是没有释放,导致内存空间浪费;

七、JVM内存布局

在这里插入图片描述

八、类的生命周期

在这里插入图片描述

九、JVM参数

9.1 JVM的参数类型

  • 标配参数:-version,-help
  • X参数(了解):-Xint,-Xmixed
  • XX参数:
    • boolean类型:-XX:+PrintGCDetails
    • KV设值类型:-XX:MetaspaceSize=128m

9.2 查看内存参数

  • -XX:+PrintFlagsInitial 主要查看初始默认(不依赖java进程)
    案例:java -XX:+PrintFlagsInitial

  • -XX:+PrintFlagsFinal 主要查看修改更新(不依赖java进程)
    案例:java -XX:+PrintFlagsFinal

  • -XX:+PrintCommandLineFlags 打印命令行参数

  • jinfo 查看进程相关数据
    案例: jinfo -flag MetaspaceSize pid

9.3 问题:

  • -Xms:初始大小内存,默认物理内存1/64,等价于-XX:InitialHeapSize;
  • -Xmx:最大分配内存,默认为物理内存1/4,等价于-XX:MaxHeapSize;
  • -Xss:设置单个线程栈的大小,一般默认为512k~1024k,等价于-XX:ThreadStackSize;

参考文章:
【JVM参数调优】
官方文档

十、常用配置

-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=heapdump.txt
-XX:+PrintGCDetails
-Xloggc:gc.log

十一、模拟内存溢出

见代码;

十二、什么条件触发GC-CMS为例

  1. eden区满了,会不会触发?
  2. 老年代满了会不会触发?
  3. 直接缓冲区满了会不会触发?
  4. 元空间满了,会不会触发?

十三、工具

13.1 jvm gc日志分析工具

https://gceasy.io/ft-index.jsp

13.2 内存快照分析工具

mat,jprofile,VisualVM

13.3 java自带

  • -jps 进程查看

  • -jstat:用于监视虚拟机各种运行状态信息的命令行工具。可以显示本地或者远程虚拟机进程中的类记载、内存、垃圾收集、JIT编译等运行数据:

jstat -gc pid #垃圾回收统计
jstat -gccapacity pid #堆内存统计
jstat -gcnew pid #新生代垃圾回收统计
jstat -gcnewcapacity pid #新生代内存统计
jstat -gcold pid #老年代垃圾回收统计
jstat -gcoldcapacity pid #老年代内存统计
jstat -gcutil pid #总结垃圾回收统计
jstat -printcompilation pid #JVM编译方法统计
jstat -class pid #类加载统计

  • -jinfo 参数配置查看

  • -jmap 内存监控:

jmap -clstats pid #打印进程的类加载器和类加载器加载的持久代对象信息
jmap -heap pid #查看进程堆内存使用情况,包括使用的GC算法、堆配置参数和各代中堆内存使用情况。
jmap -histo[:live] pid #查看堆内存中的对象数目、大小统计直方图,如果带上live则只统计活对象
jmap -dump:format=b,file=dumpFileName pid #jmap把进程内存使用情况dump到文件中

  • -jstatck线程监控

十四、思考

14.1 eden space+ from space > to space可能么? 会发生什么GC?

个人答案:可能,

14.2 Integer为什么用equals判断相等?

对应用类型,比如Integer、Long和String,进行判等,需要使用equals进行内容判等。因为引用类型的直接值是指针,使用==的话,比较的是指针,也就是两个对象在内存中的地址,即比较它们是不是同一个对象,而不是比较对象的内容。

Integer会自动拆箱:
默认情况下会缓存[-128,127]的数值,在这个值只能用==,会返回true,否则返回false。

14.3 jvm这些区,哪些是线程共享的,哪些是能抛出oom的?

JDK7 以前的运行时数据区分布图如下:
在这里插入图片描述
JDK8 以后的运行时数据区分布图如下:
在这里插入图片描述
内存溢出通俗的讲就是内存不够用了,并且 GC
通过垃圾回收也无法提供更多的内存。实际上除了程序计数器,其他区域都有可能发生 OOM, 简单总结如下:

  1. 堆内存不足是最常见的 OOM 原因之一,抛出错误信息 java.lang.OutOfMemoryError:Java heapspace,原因也不尽相同,可能是内存泄漏,也有可能是堆的大小设置不合理。
  2. 对于虚拟机栈和本地方法栈,导致 OOM 一般为对方法自身不断的递归调用,且没有结束点,导致不断的压栈操作。类似这种情况,JVM实际会抛出 StackOverFlowError , 但是如果 JVM 试图去拓展栈空间的时候,就会抛出 OOM。
  3. 对于老版的 JDK, 因为永久代大小是有限的,并且 JVM 对老年代的内存回收非常不积极,所以当我们添加新的对象,老年代发生 OOM的情况也非常常见。
  4. 随着元数据区的引入,方法区内存已经不再那么窘迫,所以相应的 OOM 有所改观,出现OOM,异常信息则变成了:“java.lang.OutOfMemoryError: Metaspace”。

在这里插入图片描述
参考:
JVM区域划分以及那些区域可能产生OOM(out of memory)

14.4 垃圾回收会回收哪些区域?

——方法区、堆。
参考:
【JVM】万字详解垃圾回收机制(面试常问)

14.5 oom之后java进程还在运行吗?

在这里插入图片描述
这段代码抛出异常了,其他线程还会运行吗?
——会运行;
——这里的栈溢出,只是一个栈帧装不下;

14.6 mysql发生死锁后,会影响其他连接吗?

——不会影响其他连接。

14.7 字符串常量池存在哪?

——堆
在JDK6.0及之前版本,字符串常量池是放在Perm Gen区(也就是方法区)中;
在JDK7.0版本,字符串常量池被移到了堆中了。至于为什么移到堆内,大概是由于方法区的内存空间太小了。

14.8 堆内存溢出会影响其他线程吗?

——不一定;
——堆内存溢出影响创建新对象的存储,但是如果有线程不用创建新对象,则不影响;

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

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

相关文章

Java实现快速排序及其动图演示

快速排序(Quicksort)是一种基于分治思想的排序算法。它通过选择一个基准元素,将数组分为两个子数组,其中一个子数组的所有元素都小于基准元素,另一个子数组的所有元素都大于基准元素,然后递归地对这两个子数…

C_11练习题答案

一、单项选择题(本大题共20小题,每小题2分,共40分。在每小题给出的四个备选项中,选出一个正确的答案,并将所选项前的字母填写在答题纸的相应位置上。) 以下叙述中正确的是(C)A.C语言不是一种高级语言 B.C语言不用编译就能被计算机执行 C.C语言能够直接访问物理地址和进行位…

Process On在线绘制流程图

目录 一.ProcessOn 1.1.介绍 1.2.直接网上使用 二.绘制门诊流程图 三.绘制住院流程图 四.绘制药库采购入库流程图 五.绘制OA会议流程图 今天就到这里了哦!!!希望能帮到你哦!!! 一.ProcessOn 1.1.介绍 ProcessOn(流程&#…

【强化学习-读书笔记】多臂赌博机 Multi-armed bandit

参考 Reinforcement Learning, Second Edition An Introduction By Richard S. Sutton and Andrew G. Barto强化学习与监督学习 强化学习与其他机器学习方法最大的不同,就在于前者的训练信号是用来评估(而不是指导)给定动作的好坏的。 …

Windows中使用pthread线程库

由于时间成本,不想使用Windows线程API,因此想用pthread线程库;但pthread是Linux默认的POSIX线程库,Windows中并不自带,需要自己配置。 因为pthread遵循POSIX标准,因此其在Windows中使用应该和Linux中大同小…

JAVA:深入探讨Map的多种遍历方式

1、简述 在现代编程中,Map(映射)是一种常见的数据结构,用于存储键-值对。在许多编程语言中,Map提供了灵活的数据组织方式,但为了充分发挥其功能,我们需要了解多种遍历方式。本文将深入探讨Map的…

国际刑警组织推出新的生物识别系统

2023 年 11 月 29 日,国际刑警组织发布了一份有关创建生物识别工具的新闻稿,至少在意大利,该工具似乎已经陷入沉默,但让我们看看为什么我们会对这个东西感兴趣。 国际刑警组织的新闻稿用了整整一段时间来讨论与隐私相关的问题&am…

【sqli靶场】第六关和第七关通关思路

目录 前言 一、sqli靶场第六关 1.1 判断注入类型 1.2 观察报错 1.3 使用extractvalue函数报错 1.4 爆出数据库中的表名 二、sqli靶场第七关 1.1 判断注入类型 1.2 判断数据表中的字段数 1.3 提示 1.4 构造poc爆库名 1.5 构造poc爆表名 1.6 构造poc爆字段名 1.7 构造poc获取账…

Android Studio实现俄罗斯方块

文章目录 一、项目概述二、开发环境三、详细设计3.1 CacheUtils类3.2 BlockAdapter类3.3 CommonAdapter类3.4 SelectActivity3.5 MainActivity 四、运行演示五、项目总结 一、项目概述 俄罗斯方块是一种经典的电子游戏,最早由俄罗斯人Alexey Pajitnov在1984年创建。…

保障事务隔离级别的关键措施

目录 引言 1. 锁机制的应用 2. 多版本并发控制(MVCC)的实现 3. 事务日志的记录与恢复 4. 数据库引擎的实现策略 结论 引言 事务隔离级别是数据库管理系统(DBMS)中的一个关键概念,用于控制并发事务之间的可见性。…

【动态规划】【广度优先搜索】LeetCode:2617 网格图中最少访问的格子数

本文涉及的基础知识点 二分查找算法合集 动态规划 题目 给你一个下标从 0 开始的 m x n 整数矩阵 grid 。你一开始的位置在 左上角 格子 (0, 0) 。 当你在格子 (i, j) 的时候&#xff0c;你可以移动到以下格子之一&#xff1a; 满足 j < k < grid[i][j] j 的格子 (i,…

聊聊分布式数据库TDSQL的技术架构

大家好&#xff0c;我是飞哥&#xff01; 咱们很多读者都是在互联网公司工作&#xff0c;大部分同学会有一种认知偏差&#xff0c;总以为互联网的业务对技术的要求是最高的。但其实不然。 比如在对延时的要求上&#xff0c;高频量化交易就比互联网的延迟要求要高得多。在数据库…

家政服务小程序预约上门,让服务更便捷

随着人们生活节奏的加快&#xff0c;家政服务行业越来越受到人们的欢迎。为了满足市场需求&#xff0c;提高服务质量&#xff0c;家政公司需要开发一款预约上门的家政服务小程序。本文将详细介绍如何制作一个预约上门的家政服务小程序。 一、登录乔拓云网后台 首先&#xff0c…

springoot集成kafka

1.常见两种模式 2.高可用 和 负载均衡 组内:消费者 一个只能消费一个分区 组外:消费者消费是订阅者模式

Element的安装以及基本使用

Element是基于Vue的网站组件库&#xff0c;用于快捷构建网页 像上面这样的样式 官网地址 Element - 网站快速成型工具 安装 npm i element-ui -S 装包命令 npm install babel-plugin-component -D 安装好之后会在package.json里面显示版本 在node_modules中会自动初始化一个 …

选择排序-排序算法

思路 选择排序&#xff08;Selection sort&#xff09;的主要思路是&#xff1a;在要排序的区间内找到一个最大的元素&#xff0c;将它放到数组的最后一个位置&#xff0c;然后在剩余的未排序区间内找到一个最大的元素&#xff0c;将它放到数组的倒数第二个位置。以此类推&…

涵盖多种功能,龙讯旷腾Module第六期:输运性质

Module是什么 在PWmat的基础功能上&#xff0c;我们针对用户的使用需求开发了一些顶层模块&#xff08;Module&#xff09;。这些Module中的一部分是与已有的优秀工具的接口&#xff0c;一部分是以PWmat的计算结果为基础得到实际需要的物理量&#xff0c;一部分则是为特定的计…

2023iEnglish学习成长营结营 助力自主阅读习惯养成

iEnglish智能英语学习解决方案日前消息,2023年最新一期的365天和1000天“iEnglish学习成长营”顺利结营。据悉,截至今年12月,完成365天和1000天每天坚持不低于30分钟的英语原版阅读人数分别累计突破15万人和2万人。而当前,21天、100天、365天以及1000天四种不同目标和意义的iEn…

中文分词演进(查词典,hmm标注,无监督统计)新词发现

查词典和字标注 目前中文分词主要有两种思路&#xff1a;查词典和字标注。 首先&#xff0c;查词典的方法有&#xff1a;机械的最大匹配法、最少词数法&#xff0c;以及基于有向无环图的最大概率组合&#xff0c;还有基于语言模型的最大概率组合&#xff0c;等等。 查词典的方法…

微信小程序 实现上传图片前裁剪功能

前言 技术支持&#xff1a; wx-cropper 裁剪 总体思路是&#xff1a;安装完wx-cropper之后就它当成组件使用。在使用页面的地方引入组件就行。上传图片的逻辑不变&#xff0c;在 通过wx.chooseMedia() Api 拿到图片之后传递给子组件&#xff0c;子组件在拿到图片进行裁剪处理等…