1.背景:
最近一段时间研发大佬们在积极的治理告警,经过一段时间的治理,现在告警情况已经有了很大的改观,但难免还有漏网之鱼;具体我们可以以下边一个例子来看:
这是一个生产的UMP告警,通过这个告警我们发现XXX这个应用的堆内存使用率为90.18%,超过了设置的告警阈值85%,所以产生了这样的一个告警;那什么是堆内存呢?
1.1.Java堆内存
Java堆内存的定义
Java堆内存是JVM内存的一部分,专门用于动态分配对象和数组。它是一个运行时数据区,从JVM启动到JVM关闭,堆内存一直存在。堆内存的大小可以通过JVM启动参数进行调整,如-Xms(
表示java虚拟机堆区内存初始内存分配的大小)
和-Xmx(
表示java虚拟机堆区内存可被分配的最大上限)
。
Java堆内存的特点
动态分配:Java堆内存允许在运行时动态分配和释放对象。
自动管理:Java具有自动垃圾回收机制(Garbage Collection, GC),自动回收不再使用的对象,防止内存泄漏。
全局访问:堆内存中的对象可以被程序中的任何部分访问,只要有对该对象的引用。
分代回收:Java堆内存通常被划分为不同的代(Generation),如新生代(Young Generation)和老年代(Old Generation),以优化垃圾回收性能。
堆内存的结构
Java堆内存通常划分为以下几个区域:
新生代(Young Generation):存储新创建的对象,分为Eden区、幸存者区(Survivor Space S0和S1)。大多数新对象首先在Eden区分配,经过几次垃圾回收后,如果对象仍然存活,则移到幸存者区,最终移到老年代。
老年代(Old Generation):存储生命周期较长的对象。经过多次垃圾回收后仍然存活的新生代对象会被移到老年代。
永久代(Permanent Generation)或元空间(Metaspace):存储类的元数据(如类定义和方法元数据)。Java 8及以后,永久代被移除,改为元空间,并且使用本地内存而不是堆内存。
Java堆内存的工作原理
对象分配:当通过new关键字创建一个对象时,JVM会在堆内存中分配空间。比如:在这个例子中,new Person("John", 25)会在堆内存中分配空间来存储Person对象。
public class Main {
public static void main(String[] args) {
// 创建一个对象
Person person = new Person("John", 25);
}
}
class Person {
String name;
int age;
//构造方法
Person(String name, int age) {
this.name = name;
this.age = age;
}
}
垃圾回收:Java的垃圾回收机制自动回收不再使用的对象,释放堆内存空间。垃圾回收器(Garbage Collector)会周期性地扫描堆内存,识别不再有任何引用指向的对象,并回收它们占用的内存。
垃圾回收的过程大致分为以下几步:
标记:标记出所有存活的对象。
清除:清除所有未被标记的对象,释放它们占用的内存。
压缩:(可选)将存活的对象移到堆的一端,减少内存碎片,提高分配效率。
堆内存管理中的问题
内存泄漏:虽然Java有垃圾回收机制,但不正确的代码设计仍可能导致内存泄漏,即对象虽然不再使用但仍然被引用,无法被回收。
内存溢出(OutOfMemoryError):当堆内存被耗尽且垃圾回收无法释放足够内存时,会抛出OutOfMemoryError
。
性能问题:频繁的垃圾回收会影响应用性能,因此需要优化内存使用和垃圾回收策略。
通过对堆内存和垃圾回收简单的了解**(备注,由于不是专业开发可能对堆内存和垃圾回收阐述的不是特别专业,只是作为背景知识补充了解问题
标签:Java,对象,保障,回收,新视角,内存,告警,缺陷,垃圾 From: https://www.cnblogs.com/Jcloud/p/18237238