浅谈java内存管理与内存溢出异常

作者:Wilange 时间:2022-04-22 15:03:18 

说到内存管理,笔者这里想先比较一下java与C、C++之间的区别:

在C、C++中,内存管理是由程序员负责的,也就是说程序员既要完成繁重的代码编写工作又要时常考虑到系统内存的维护

在java中,程序员无需考虑内存的控制和维护,而是交由JVM自动管理,这样就不容易出现内存泄漏和溢出的问题。然而,一旦出现内存泄漏和溢出方面的问题,如果不了解JVM的内存管理机制就很难找到错误所在。

1.JVM运行时数据区

JVM在运行java程序的时候会将它所管理的内存划分为若干个不同的区域,这些区域不仅有自己的用途,还有创建和销毁的时间。一般来说包含以下几个运行时数据区:

浅谈java内存管理与内存溢出异常

其中的橙色区域是各个线程私有的,即每个线程都会有自己的一份,而绿色区域是各个线程共享的。

2.java对象的创建

浅谈java内存管理与内存溢出异常

类加载检查

当JVM扫描到new关键字时,首先会去检查这个指令的参数是否能够在常量池中定位到一个类的符号引用,并且检查这个类的符号引用代表的类是否已被加载、解析和初始化过。如果没有,就必须先执行相应的类加载过程。

内存分配

当类加载检查通过后,JVM需要为新生对象分配内存,即是把一块确定大小的内存从java堆中划分出来。常用的划分方法有两种:指针碰撞(要求堆内存绝对规整)、空闲列表(堆内存并不规整)。

内存初始化

JVM需要将分配到的内存空间都初始化为零值(不包括对象头),这就保证了对象的实例字段在java代码中可以不赋初始值就直接使用,也就是说程序能够访问到这些字段的数据类型所对应的零值。

对象初始化

执行<init>方法,将对象按照程序员的意愿进行初始化。

3.对象的访问定位

对象创建好了,我们还希望能够快速的访问到这些对象,这就需要JVM栈上的reference(引用)数据来找到堆中的具体对象,而目前使用最多的访问方式有“句柄方式”和“直接指针”两种。

使用句柄方式访问的话,就需要在堆中划分一部分内存来作为句柄池,reference变量中存储的就是对象的句柄地址,而句柄中包含了对象实例数据和类型数据各自的具体地址信息。

浅谈java内存管理与内存溢出异常

使用直接指针访问的话,reference变量中存储的直接就是对象地址,但是需要考虑如何放置类型数据的相关信息。

浅谈java内存管理与内存溢出异常

4.内存溢出异常

JVM运行时数据区除了PC寄存器之外,其他的内存区域都有可能发生内存溢出的异常情况。PC寄存器是唯一一个在JVM规范中没有规定任何OutOfMemoryError(OOM)情况的区域。

堆溢出

java中的堆用于存储对象实例,如果不断地创建对象,并且保证GC Roots到对象之间有可达路径以避免GC的回收处理,那么在对象的数量达到最大堆的容量限制后就会发生堆溢出的异常情况。

栈溢出(包括JVM栈和本地方法栈)

1.如果线程请求的栈深度大于JVM所允许的最大深度,将抛出StackOverflowError异常;

2.如果JVM在扩展栈时无法申请到足够的内存空间,将抛出OutOfMemoryError异常。

此外,还有方法区溢出、常量池溢出、本机内存溢出等等。

来源:http://www.cnblogs.com/Wilange/archive/2017/10/17/7654964.html

标签:java,内存溢出,异常,内存管理
0
投稿

猜你喜欢

  • Java实现将每日新闻添加到自己博客中

    2023-02-08 16:20:43
  • 从搭建Struts2 开发环境说起

    2023-11-18 08:54:53
  • 详细解读JAVA多线程实现的三种方式

    2022-01-14 04:35:31
  • ServletWebServerApplicationContext创建Web容器Tomcat示例

    2023-10-12 12:28:33
  • Java与Node.js利用AES加密解密出相同结果的方法示例

    2021-09-11 21:06:58
  • java 文件上传到读取文件内容的实例

    2023-11-09 22:00:27
  • c语言动态数组示例

    2023-11-02 22:56:44
  • JavaMap两种遍历方式keySet与entrySet详解

    2022-04-17 14:36:29
  • SpringBoot Nacos实现自动刷新

    2023-09-16 04:17:09
  • 解析Java的Hibernate框架中的持久化类和映射文件

    2023-08-19 15:00:05
  • Java实战之实现一个好用的MybatisPlus代码生成器

    2023-06-18 02:16:10
  • 详解Java的Spring框架下bean的自动装载方式

    2022-10-23 08:13:59
  • java模拟hibernate一级缓存示例分享

    2023-06-18 08:43:55
  • 详解Flutter中视频播放器插件的使用教程

    2023-06-15 23:47:31
  • C语言时间函数之strftime()详解

    2023-06-26 02:42:32
  • Java链表(Linked List)基本原理与实现方法入门示例

    2021-10-12 05:49:14
  • Android客户端与服务端数据加密传输方案详解

    2023-07-14 13:55:37
  • 解决Java中properties文件编码问题

    2022-07-21 14:09:06
  • 详解Java动态字节码技术

    2022-06-20 03:20:20
  • FeignClient中name和url属性的作用说明

    2023-06-04 13:21:55
  • asp之家 软件编程 m.aspxhome.com