zoukankan      html  css  js  c++  java
  • 内存结构篇:堆

    一、定义

    Java 堆(Heap)(线程共享

    • 所有线程共享的一块内存区域,在虚拟机启动时创建。
    • 此内存区域的唯一目的就是存放对象实例,“几乎”所有的对象实例都在这里分配内存用new创建的类变量才是实例

    特点:

    • 它是线程共享的,堆中对象都需要考虑线程安全的问题
    • 有垃圾回收机制,是垃圾回收的主要区域(“GC堆”)(Garbage Collected Heap)
    • 现代的垃圾收集器基本都是采用分代收集算法,其主要的思想是针对不同类型的对象采用不同的垃圾回收算法。可以将堆分成两块:
      • 新生代(Young Generation)
      • 老年代(Old Generation)
    • 不需要连续内存,并且可以动态增加其内存,增加失败会抛出 OutOfMemoryError 异常(但对于大对象如数组对象,多数虚拟机实现出于实现简单、存储高效的考虑,很可能会要求连续的内存空间)

    可以通过 -Xms 和 -Xmx 这两个虚拟机参数来指定一个程序的堆内存大小,第一个参数设置初始值,第二个参数设置最大值

    java -Xms1M -Xmx2M HackTheJava

    二、堆内存溢出

    对象实例一直被使用,同时一直增加对堆内存的占用,导致堆内存无法释放,出现 OutOfMemoryError 异常

    /**
     * 演示堆内存溢出 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); // hello, hellohello, hellohellohellohello ...
                    a = a + a;  // hellohellohellohello
                    i++;
                }
            } catch (Throwable e) {
                e.printStackTrace();
                System.out.println(i);
            }
        }
    }
    

    报错信息:

    24
    java.lang.OutOfMemoryError: Java heap space
    	at java.util.Arrays.copyOf(Arrays.java:3332)
    	at java.lang.AbstractStringBuilder.ensureCapacityInternal(AbstractStringBuilder.java:124)
    	at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:448)
    	at java.lang.StringBuilder.append(StringBuilder.java:136)
    	at cn.itcast.jvm.t1.heap.Demo1_5.main(Demo1_5.java:19)
    

    三、堆内存诊断

    1. jps 工具
    • 查看当前系统中有哪些 java 进程
    1. jmap 工具
    • 查看堆内存占用情况 jmap - heap 进程id
    1. jconsole 工具
    • 图形界面的,多功能的监测工具,可以连续监测
    1. jvisualvm 工具
      • 图形界面,和 jconsole 类似,可以使用堆 Dump ,查看对象个数等信息

    案例:

    • 垃圾回收后,内存占用仍然很高
    /**
     * 演示查看对象个数 堆转储 dump
     */
    public class Demo1_13 {
    
        public static void main(String[] args) throws InterruptedException {
            List<Student> students = new ArrayList<>();
            for (int i = 0; i < 200; i++) {
                students.add(new Student());
    //            Student student = new Student();
            }
            Thread.sleep(1000000000L);
        }
    }
    class Student {
        private byte[] big = new byte[1024*1024];
    }
    
  • 相关阅读:
    MongoDB学习(附录一) 安装mongodb3.6时碰到的问题
    详细图解mongodb下载、安装、配置与使用
    大数据时代的数据存储,非关系型数据库MongoDB
    python获取风和天气城市数据 ID
    智能车学习(二十一)——浅谈CCD交叉以及横线摆放
    智能车学习(二十)——浅谈C车硬连接与软连接
    智能车学习(十九)——硬件电路设计
    智能车学习(十八)——电机学习
    智能车学习(十七)——舵机学习
    智能车学习(十六)——CCD学习
  • 原文地址:https://www.cnblogs.com/flypig666/p/13975107.html
Copyright © 2011-2022 走看看