JVM学习-堆空间(一)

堆空间

每个进程(JVM实例)拥有唯一的方法区和堆空间,拥有唯一的Runtime实例(基于饿汉式方式),线程共享进程的方法区和堆空间,每个线程拥有独立的程序计数器、本地方法栈和虚拟机栈。

  • 一个JVM实例只存在一个堆内存,堆是Java内存管理的核心区域
  • Java堆区在JVM启动的时候即被创建,其空间大小也就确定了,是JVM管理的最大一块存储空间
    • 堆内存可以调节
  • 堆可以处于物理上不连续的内存空间中,但在逻辑上是连续的
  • 所有的线程共享Java堆,在这里还可以划分私有的缓冲区(Thread Local Allocation Buffer,TLAB)
  • Java虚拟机规范中对Java堆的描述是:所有对象实例及数组都应该在运行时分配在堆上
    • “几乎”所有的对象实例都在这里分配内存 – 从实际使用角度看
  • 数组和对象可能永远不会存储在栈上,因为栈帧中保存引用,这个引用指向对象或者数组在堆中的位置
  • 在方法结束后,堆中的对象不会马上移除,仅仅在垃圾收集的时候才会被移除
  • 堆是GC执行垃圾回收的重点区域
    在这里插入图片描述
public class SimpleHeap {
    private int id;
    public SimpleHeap(int id) {
        this.id = id;
    }
    public void show() {
        System.out.println("My ID is:" + id);
    }
    public static void main(String[] args) {
        SimpleHeap s1 = new SimpleHeap(1);
        SimpleHeap s2 = new SimpleHeap(2);
    }
}

在这里插入图片描述

堆内存细分
  • Java7及之前堆内存逻辑上分为三个部分:新生区+养老区+永久代
    • Young Generation Space 新生代 Young/New
      • 划分为Eden区和Survivor区
    • Tenure Generation Space 养老区 Old/Tenure
    • Permanent Space 永久代 Perm
  • Java8及之前堆内存逻辑上分为三个部分:新生区+养老区+元空间
    • Young Generation Space 新生代 Young/New
      • 划分为Eden区和Survivor区
    • Tenure Generation Space 养老区 Old/Tenure
    • Meta Space 元空间 Meta
      约定:新生区<->新生代<->年轻代 养老区<->老年区<->老年代 永久区<->永久代
      在这里插入图片描述
堆空间大小设置
  • Java堆区用于存储Java对象实例,堆的大小在JVM启动时就已经设定好了,可以通过"-Xmx"和“-Xms”来进行设置
    • -Xms用于表示堆区的起始内存,等价于-XX:InitialHeapSize
    • -Xmx则用于表示堆区的最大内存,等价于-XX:MaxHeapSize
  • 一旦堆区中的内存大小超过"-Xmx"所指定的最大内存时,将会抛出OutOfMemoryError异常
  • 通常会将-Xms和-Xmx两个参数配置相同的值,目的为了能够在Java垃圾回收机制清理完堆后不需要重新分隔计算堆区的大小,从而提高性能
  • 默认情况下,初始内存大小:物理电脑内存大小/64,最大内存大小:物理电脑内存大小/4
/**
 * 1.设置内存大小
 * -Xms用来设置堆空间(年轻代+老年代)的初始内存大小
 * -X 是JVM运行参数
 *  ms:memory start
 * -Xmx用来设置堆空间(年轻代+老年代)的最大内存大小
 * 2.默认堆空间大小
 * 默认情况下,初始内存大小:物理电脑内存大小/64,
 *             最大内存大小:物理电脑内存大小/4
 * 3.手动设置 -Xms600m -Xmx600m
 * 开发中建议将初始堆内存和最大堆内存设置成相同值
 * 4.查看设置参数
 *   1) jps | jstat -gc pid
 *   2)-XX:+PrintGCDetails(在执行时添加参数)
 */
public class HeapSpaceInitial {
    public static void main(String[] args) {
        //返回Java虚拟机堆内存大小
        long initialMemory = Runtime.getRuntime().totalMemory()/1024/1024;
        //返回Java虚拟机试图使用的最大内存量
        long maxMemory = Runtime.getRuntime().maxMemory()/1024/1024;
        System.out.println("-Xms:" + initialMemory + "M");
        System.out.println("-Xmx:" + maxMemory + "M");
        System.out.println("系统内存大小:" + initialMemory * 64 / 1024 +"G");
        System.out.println("系统内存大小:" + maxMemory * 4 / 1024 +"G");
    }
}
//运行结果--计算单位1000
-Xms489M
-Xmx7246M
系统内存大小:30G
系统内存大小:28G
//jps/jstat -gc pid查看内存使用情况
C:\Users\Administrator\IdeaProjects\jvm\target\classes\com\chapter05>jps
3696 KotlinCompileDaemon
4832 Jps
10680 Launcher
10872 RemoteMavenServer36
8668
8716 HeapSpaceInitial

C:\Users\Administrator\IdeaProjects\jvm\target\classes\com\chapter05>jstat -gc 8716
 S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT
21504.0 21504.0  0.0    0.0   131072.0 10485.8   348160.0     0.0     4480.0 770.4  384.0   75.9       0    0.000   0      0.000    0.000
-----------------------------------------------------------------------------------------------------------------------
//添加-XX:+PrintGCDetails
Heap
 PSYoungGen      total 152576K, used 10486K [0x0000000716300000, 0x0000000720d00000, 0x00000007c0000000)
  eden space 131072K, 8% used [0x0000000716300000,0x0000000716d3d8b8,0x000000071e300000)
  from space 21504K, 0% used [0x000000071f800000,0x000000071f800000,0x0000000720d00000)
  to   space 21504K, 0% used [0x000000071e300000,0x000000071e300000,0x000000071f800000)
 ParOldGen       total 348160K, used 0K [0x00000005c2800000, 0x00000005d7c00000, 0x0000000716300000)
  object space 348160K, 0% used [0x00000005c2800000,0x00000005c2800000,0x00000005d7c00000)
 Metaspace       used 3491K, capacity 4498K, committed 4864K, reserved 1056768K
  class space    used 387K, capacity 390K, committed 512K, reserved 1048576K
OutOfMemory事例
public class OOMTest {
    public static void main(String[] args) {
        List<Picture> list = new ArrayList<>();
        while (true) {
            try {
                Thread.sleep(20);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            list.add(new Picture(new Random().nextInt(1024 * 1024)));
        }
    }
}

class Picture {
    private byte[] pixels;
    public Picture(int length) {
        this.pixels = new byte[length];
    }
}
//执行结果
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
	at com.chapter06.Picture.<init>(OOMTest.java:30)
	at com.chapter06.OOMTest.main(OOMTest.java:20)

在这里插入图片描述

  • 22
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
算法与数据结构涵盖了以下主要内容: 数据结构(Data Structures): 逻辑结构:描述数据元素之间的逻辑关系,如线性结构(如数组、链表)、树形结构(如二叉树、、B树)、图结构(有向图、无向图等)以及集合和队列等抽象数据类型。 存储结构(物理结构):描述数据在计算机中如何具体存储。例如,数组的连续存储,链表的动态分配节点,树和图的邻接矩阵或邻接表表示等。 基本操作:针对每种数据结构,定义了一系列基本的操作,包括但不限于插入、删除、查找、更新、遍历等,并分析这些操作的时间复杂度和空间复杂度。 算法: 算法设计:研究如何将解决问题的步骤形式化为一系列指令,使得计算机可以执行以求解问题。 算法特性:包括输入、输出、有穷性、确定性和可行性。即一个有效的算法必须能在有限步骤内结束,并且对于给定的输入产生唯一的确定输出。 算法分类:排序算法(如冒泡排序、快速排序、归并排序),查找算法(如顺序查找、二分查找、哈希查找),图论算法(如Dijkstra最短路径算法、Floyd-Warshall算法、Prim最小生成树算法),动态规划,贪心算法,回溯法,分支限界法等。 算法分析:通过数学方法分析算法的时间复杂度(运行时间随数据规模增长的速度)和空间复杂度(所需内存大小)来评估其效率。 学习算法与数据结构不仅有助于理解程序的内部工作原理,更能帮助开发人员编写出高效、稳定和易于维护的软件系统。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值