二十、Java内存泄漏概念、造成原因及检测方式(全)

发布于:2024-05-07 ⋅ 阅读:(29) ⋅ 点赞:(0)


一、Java内存泄漏概念、造成原因及检测方式(全)

Java内存泄漏概念、造成原因及检测方式(全)

二、其他

1.jmap命令

jmap -dump:format=b,file=C:\users\Administrator\Desktop\my123.hprof 30460

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import warnings
warnings.filterwarnings('ignore')
import  ssl
ssl._create_default_https_context = ssl._create_unverified_context

2.java VisualVM查看.hprof文件

java VisualVM查看.hprof文件

刚打开插件,插件可能没法用
在这里插入图片描述
点下最新版本,会报无法连接,说明插件地址配的有问题
在这里插入图片描述
怎么解决:
在这里插入图片描述
打开网址:visualvm官网
visualvm对应的jdk版本
找到自己安装的JDK 命令:java -version
在这里插入图片描述
java version “1.8.0_211”
Java™ SE Runtime Environment (build 1.8.0_211-b12)
Java HotSpot™ 64-Bit Server VM (build 25.211-b12, mixed mode)java version “1.8.0_211”
Java™ SE Runtime Environment (build 1.8.0_211-b12)
Java HotSpot™ 64-Bit Server VM (build 25.211-b12, mixed mode)

在这里插入图片描述
点进去复制上面的
在这里插入图片描述
粘贴过来
在这里插入图片描述
回到可用插件 安装 visual GC
在这里插入图片描述
安装完关了重启
在这里插入图片描述

JVM中的幸存者区、新生代、老年代、元空间、压缩类空间分别是概念,有什么实际的作用,什么情况应该警惕?

  1. 新生代(Young Generation):
  • 概念:新生代是大多数新创建的对象首先分配的地方。它被分为三部分:Eden区和两个Survivor区(S0和S1)。

  • 作用:新生代的主要目的是为了快速分配和回收短期对象。大多数对象在创建后很快就不再使用,所以它们在新生代中被分配和回收。这种快速的分配和回收策略可以减少内存碎片,提高内存利用率。

  • 警惕:如果新生代的大小设置得太小,会导致对象频繁地被复制到Survivor区或者提升到老年代,触发更多的Minor GC。如果Minor GC的频率非常高,并且每次GC的耗时也很长,那就需要考虑增大新生代的大小。

  1. 幸存者区(Survivor Spaces):
  • 概念:幸存者区是新生代的一部分,用于存放在Minor GC中幸存下来的对象。幸存者区有两个:S0和S1。在Minor GC之后,Eden区和一个Survivor区的存活对象会被复制到另一个Survivor区。

  • 作用:Survivor区的主要目的是为了减少对象直接进入老年代的机会。通过在Survivor区之间复制对象,JVM可以识别出那些经历了多次GC仍然存活的对象,然后将其提升到老年代。

  • 警惕:如果Survivor区的大小设置得太小,会导致对象在Survivor区之间频繁地复制,增加GC的开销。同时,也会使更多的对象直接进入老年代,加速老年代的填满。

  1. 老年代(Old Generation):
  • 概念:老年代是用于存放长期存活的对象的地方。通常,一个对象如果在新生代中经历了若干次Minor GC仍然存活,就会被提升到老年代。

  • 作用:老年代的主要目的是为了存放长期存活的对象,减少Full GC的频率。因为老年代的对象通常比较稳定,所以Full GC的频率相对Minor GC要低得多。

  • 警惕:如果老年代被填满,就会触发Full GC。频繁的Full GC会严重影响应用的性能,因为Full GC的暂停时间通常比Minor GC长得多。如果老年代的使用量持续增长,并频繁触发Full GC,那就需要考虑增大老年代的大小,或者检查是否存在内存泄漏。

  1. 元空间(Metaspace):
  • 概念:元空间是用于存储类的元数据的地方,如类的名称、字段、方法等。在Java 8之前,这部分数据被存储在永久代(PermGen)中。

  • 作用:元空间的主要目的是为了存储类的元数据,支持类的加载和卸载。与永久代不同,元空间可以自动扩展其大小。

  • 警惕:虽然元空间可以自动扩展,但如果元空间的使用量持续增长,最终也会耗尽所有可用空间,导致OutOfMemoryError: Metaspace错误。这通常表示存在类加载泄漏,即某些类加载器不断地加载新的类,但从未卸载它们。

  1. 压缩类空间(Compressed Class Space):
  • 概念:压缩类空间是元空间的一部分,用于存储压缩后的类数据。这是为了节省内存空间,特别是在64位系统上。

  • 作用:压缩类空间的主要目的是为了减少类元数据的内存占用。通过将类数据压缩为32位的指针,JVM可以在64位系统上节省大量的内存。

  • 警惕:压缩类空间的大小是固定的,默认为1GB。如果压缩类空间被耗尽,JVM将无法加载新的类,并抛出OutOfMemoryError: Compressed class space错误。这通常表示应用加载了大量的类,超出了压缩类空间的容量。

理解这些概念及其作用对于优化Java应用的性能至关重要。建议你密切监控这些内存区域的使用情况,特别是老年代和元空间。频繁的Full GC,或者元空间的持续增长,通常是潜在问题的红色警报。同时,也要注意新生代和Survivor区的大小设置。过小的新生代或Survivor区会导致更频繁的GC,而过大的新生代又可能延迟对象的提升,增加Full GC的频率。