JVM内存区域的划分,哪些区域可能产生OutOfMemory

2024-04-30 08:48

本文主要是介绍JVM内存区域的划分,哪些区域可能产生OutOfMemory,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、JVM内存区域划分

通常可以把JVM内存区域划分为程序计数器,虚拟机栈,本地方法栈,堆,方法区,运行时常量池。其中,有的区域是以线程为单位,有的区域则是整个JVM进程唯一的。

  • 程序计数器。程序计数器是一块比较小的内存区域,可以看做当前线程执行的字节码的行号指示器。在JVM规范中,每个线程都有它自己的程序计数器,并且任何时间一个线程都只有一个方法在执行。
  • Java虚拟机栈。每个线程在创建时都会创建一个虚拟机栈,其内部保存一个个的栈帧,对应一次Java方法调用。栈帧中存储着局部变量表,操作数栈,动态链接,方法正常退出或者异常退出定义等。
  • 本地方法栈。它和Java虚拟机栈非常相似。它们的区别在于Java虚拟机栈为虚拟机执行Java方法服务,而本地方法栈为虚拟机执行Native方法服务。
  • 堆。它是Java内存管理的核心区域,用来放置Java对象实例。几乎所有创建的Java对象实例都被直接分配在堆上。堆被所有线程共享。堆也是垃圾收集器重点照顾的区域,堆内空间还会被不同垃圾收集器进行划分。
  • 方法区。方法区和堆一样,也是被所有线程共享的区域。它用来存储已被加载的class的信息。比如类名,访问修饰符,常量池等。由于早期的Hotspot JVM实现,很多人习惯将方法区成为永生代。Oracle JDK8将永久代移除,同时增加了元数据区(MetaSpace)。
  • 运行时常量池。运行时常量池是方法区的一部分。Java的常量池可以存储各种常量信息。
  • 直接内存(DirectMemory)。直接内存并不是虚拟机运行时数据区的一部分,但是在NIO中,可以直接分配DirectMemory,然后通过存储在堆中的一些DirectByteBuffer对象作为这块区域的引用进行操作。

 二、OutOfMemoryError异常

OOM通俗点儿说就是内存不够用了。没有空闲内存,并且垃圾收集器也无法提供更多内存。在抛出OutOfMemoryError之前,垃圾收集器会被触发,尽其所能去清理出空间。

除了程序计数器,其他区域都有可能因为空间不足发生OutOfMemoryError。

  • 堆内存不足是最常见的OOM原因之一,抛出的错误信息是“java.lang.OutOfMemoryError:Java heap space”,原因可能千奇百怪,例如:可能存在内存泄露问题,也很有可能是堆的大小不合理,比如我们要处理较大的数据量,但是没有显示指定JVM堆大小或者指定数值偏小;或者出现JVM处理引用不及时,当时堆积起来,内存无法释放等。
  • Java虚拟机栈和本地方法栈抛出OOM异常。如果我们写一段程序不断进行递归调用,没有退出条件,这就会导致不断的进行压栈。类似这种情况,JVM会抛出StackOverFlowError;如果JVM视图去扩展栈空间的时候失败,就会抛出OutOfMemoryError。
  • 方法区。对于老版本的JDK,因为永生代的大小是有限的,而且JVM对永生代垃圾收集非常不积极,当我们不断添加新类型的时候,永生代会出现OutOfMemoryError异常。抛出异常信息“java.lang.OutOfmemoryError:PermGen space”。而随着元数据区的引入,方法区内存已经不那么窘迫,所以OOM有所该观,出现OOM,异常信息则成了“java.lang.OutOfMemoryError:Metaspace”。
  • 直接内存不足,也会导致OOM。

这篇关于JVM内存区域的划分,哪些区域可能产生OutOfMemory的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/948414

相关文章

JVM 的类初始化机制

前言 当你在 Java 程序中new对象时,有没有考虑过 JVM 是如何把静态的字节码(byte code)转化为运行时对象的呢,这个问题看似简单,但清楚的同学相信也不会太多,这篇文章首先介绍 JVM 类初始化的机制,然后给出几个易出错的实例来分析,帮助大家更好理解这个知识点。 JVM 将字节码转化为运行时对象分为三个阶段,分别是:loading 、Linking、initialization

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

浅析Spring Security认证过程

类图 为了方便理解Spring Security认证流程,特意画了如下的类图,包含相关的核心认证类 概述 核心验证器 AuthenticationManager 该对象提供了认证方法的入口,接收一个Authentiaton对象作为参数; public interface AuthenticationManager {Authentication authenticate(Authenti

Spring Security--Architecture Overview

1 核心组件 这一节主要介绍一些在Spring Security中常见且核心的Java类,它们之间的依赖,构建起了整个框架。想要理解整个架构,最起码得对这些类眼熟。 1.1 SecurityContextHolder SecurityContextHolder用于存储安全上下文(security context)的信息。当前操作的用户是谁,该用户是否已经被认证,他拥有哪些角色权限…这些都被保

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

Java架构师知识体认识

源码分析 常用设计模式 Proxy代理模式Factory工厂模式Singleton单例模式Delegate委派模式Strategy策略模式Prototype原型模式Template模板模式 Spring5 beans 接口实例化代理Bean操作 Context Ioc容器设计原理及高级特性Aop设计原理Factorybean与Beanfactory Transaction 声明式事物

NameNode内存生产配置

Hadoop2.x 系列,配置 NameNode 内存 NameNode 内存默认 2000m ,如果服务器内存 4G , NameNode 内存可以配置 3g 。在 hadoop-env.sh 文件中配置如下。 HADOOP_NAMENODE_OPTS=-Xmx3072m Hadoop3.x 系列,配置 Nam

Java进阶13讲__第12讲_1/2

多线程、线程池 1.  线程概念 1.1  什么是线程 1.2  线程的好处 2.   创建线程的三种方式 注意事项 2.1  继承Thread类 2.1.1 认识  2.1.2  编码实现  package cn.hdc.oop10.Thread;import org.slf4j.Logger;import org.slf4j.LoggerFactory

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟 开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚 第一站:海量资源,应有尽有 走进“智听