- 通过关键字new创建的对象都会使用堆来存储
- 有垃圾回收机制
- 堆是线程共享的,堆中的所有对象都需要考虑线程安全问题
// 在配置运行环境的Environment variables中进行配置(如下修改为256k)-Xmx8m
堆出现内存溢出问题只有一种情况就是创建对象过多:/*正常情况下,我们的创建的对象在不使用的情况下就会被自动垃圾回收但如果出现异常,导致我们不断创建新对象且保存就对象就会导致堆内存溢出*/package cn.itcast.jvm.t1.heap;import java.util.ArrayList;import java.util.List;/** * 演示堆内存溢出 java.lang.OutOfMemoryError: Java heap space * -Xmx8m */public class Demo1_5 {public static void main(String[] args) {int i = 0;try {List<String> list = new ArrayList<>();String a = "hello";while (true) {list.add(a); // 这里将旧对象保存下来a = a + a;// 这里不断创建新对象i++;}} catch (Throwable e) {e.printStackTrace();System.out.println(i);}}}
堆内存问题诊断我们在正常运行中堆的内存占有是非常重要,因此JVM为我们提供了四种方法来检查堆内存问题首先我们给出用于诊断堆内存问题的参考代码:
package cn.itcast.jvm.t1.heap;/** * 演示堆内存 */public class Demo1_4 {public static void main(String[] args) throws InterruptedException {// 第一阶段:没有对象System.out.println("1...");Thread.sleep(30000);// 第二阶段:制造一个对象,占用堆byte[] array = new byte[1024 * 1024 * 10];System.out.println("2...");Thread.sleep(20000);// 第三阶段:释放对象,并进行垃圾回收,这时堆变小array = null;System.gc();System.out.println("3...");Thread.sleep(1000000L);}}
我们的JVM为我们提供了四种方法来检测堆的状况:- jps工具
// jps用于查看当前系统中有哪些java进程// 我们直接在IDEA的输入台输入即可jps
- jmap工具
// jmap用于查看当前系统中堆内存占用情况(静态形式)// 我们直接在IDEA的输入台输入即可jmap -heap 进程id// 我们可以看到Heap Usage就是内存管理// 其中Eden space 为新产生的堆内存// 其中Old Generation 为之前产生的堆内存
- jconsole工具
// jconsole用于查看当前系统中堆内存占用情况(图形化界面app展示)// 我们直接在IDEA的输入台输入即可jconsole
- jvisualvm工具
// jvisualvm用于查看当前系统中堆内存占用情况(图形化界面app展示)// 我们直接在IDEA的输入台输入即可jvisualvm
方法区这小节我们来介绍JVM内存结构中的方法区方法区简介我们首先来简单介绍一下方法区:
- 方法区是所有java虚拟机共享的一片区域
- 方法区中存放着所有类的所有信息,包括有属性,方法,构造方法等
- 方法区在虚拟机启动的一瞬间被创建,同样在虚拟机停止时方法区进行销毁
- 方法区和程序计数器一样只是一个概念
- 我们在实际开发中,jdk1.8之前采用的是永久代,在jdk1.8及以后均采用元空间
文章插图
方法区内存溢出问题方法区同样存在有内存溢出问题,但并不常见
我们将方法区的讲解分为两部分,有永久代也有元空间的讲解:
- 永久代内存溢出问题
// 永久代的概念仅存在于jdk1.8之前,我们可以通过-XX来控制永久代大小// 当方法区为永久代时,溢出就显示错误java.lang.OutOfMemoryError: PermGen spacepackage cn.itcast.jvm;import com.sun.xml.internal.ws.org.objectweb.asm.ClassWriter;import com.sun.xml.internal.ws.org.objectweb.asm.Opcodes;/** * 演示永久代内存溢出java.lang.OutOfMemoryError: PermGen space * -XX:MaxPermSize=8m */public class Demo1_8 extends ClassLoader {public static void main(String[] args) {int j = 0;try {Demo1_8 test = new Demo1_8();for (int i = 0; i < 20000; i++, j++) {ClassWriter cw = new ClassWriter(0);cw.visit(Opcodes.V1_6, Opcodes.ACC_PUBLIC, "Class" + i, null, "java/lang/Object", null);byte[] code = cw.toByteArray();test.defineClass("Class" + i, code, 0, code.length);}} finally {System.out.println(j);}}}
经验总结扩展阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 【lwip】08-ARP协议一图笔记及源码实现
- 用一台笔记本电脑如何赚钱(笔记本电脑赚钱的办法)
- 小米笔记本Pro15增强版评测_小米笔记本Pro15增强版评测表现
- 笔记本电脑CF中烟雾头怎么调(win10cf新版本烟雾保护头怎么调)
- 笔记本电脑配置高低怎么区分(笔记本电脑看什么配置判断好坏)
- 四 【单片机入门】应用层软件开发的单片机学习之路-----ESP32开发板PWM控制电机以及中断的使用
- pytorch、paddlepaddle等环境搭建 深度学习环境搭建常用网址、conda/pip命令行整理
- 三十九 Java开发学习----SpringBoot整合mybatis
- 2023年圣诞节学习运有所提升的星座智慧多多成绩提升
- 电脑开不了机怎么办简单方法(笔记本电脑开不了机)