JVM篇-堆

1.概述

  • 一个JVM实例只存在一个堆内存,堆也是Java内存管理的核心区域.
  • Java堆区在JVM启动时即被创建,其空间大小也就确定了.是JVM管理的最大的一块内存空间.(堆内存的大小是可以调节的).
  • <<Java虚拟机规范>>规定,堆可以处于物理上不连续的内存空间中,但逻辑上它应该被视为连续的.
  • 同一个JVM进程的所有线程公享堆空间,在这里还可以划分线程私有的缓冲区(Thread Local Allocation Buufer,TLAB).
  • 几乎所有的对象实例以及数组都应当在运行时分配在堆上.(并不是绝对的所有对象).
  • 数组和对象可能永远不会存储在栈上,因为栈帧中保存引用,这个引用指向对象或数组在堆中的位置.
  • 方法结束后,堆中的对象不会马上被移除,仅仅在垃圾收集的时候才被移除.
  • 堆是GC(Garbage Collection,垃圾收集器)执行垃圾回收的重点区域.
  • Java7及之前的版本堆内存逻辑上分为三部分:新生代(Young Generation Space) (又被分为Eden区和Survivor区)+ 老年代(Tenure Generation Space) +永久代(Permanent Space)[1];Java8及以后版本为:新生代(Young Generation Space) (又被分为Eden区和Survivor区)+ 老年代(enure Generation Space) +元空间(Meta) [2].

元空间不包含堆空间内: -Xms10m Xmx10m 设置jvm启动参数初始堆空间和最大堆空间为10m,使用JDK自带的jvisualvm工具中的Visual GC插件可以看到Eden +Survivor 0 + Survivor 1 + Old Generation = 10m,Metaspace = 9.5m .由此可见堆空间不包括元空间.栈/堆/方法区

2.堆内存设置

  • -Xms (-X:是jvm的运行参数,ms:memory start)用于设置堆区的起始内存,等价于 -XX:InitialHeapSize
  • -Xmx ()用于设置堆区最大内存,等价于 -XX:MaxHeapSize
  • 一旦堆区的内存超过 -Xmx 指定的最大内存就会抛出OutOfMemoryError.
  • 通常会将-Xms和-Xmx设置为相同的值,其目的是为了能够在Java垃圾回收机制清理完堆区后不需要重新分割计算堆区大小,从而提高性能.
  • 默认情况下初始内存大小为物理电脑内存的1/64;最大内存为物理电脑内存的1/4.
  • 几乎所有的对象都是在Eden区new出来的,除非对象非常大,Eden区放不下.
  • 绝大部分的对象的销毁都是在新生代进行的.
  • -Xmn 设置新生代空间的大小.如果此值与XX:NewRatio的值矛盾,以-Xmn为准.一般不设置.

import java.math.BigDecimal;

/**
* -Xmx10m -Xmx10m -XX:+PrintGCDetials
* 设置堆起始内存和最大内存为10m, 打印堆和垃圾回收信息
*/
public class TestMain {
public static void main(String[] args) {

//程序当前堆内存(字节)
BigDecimal totalMemoryByte = new BigDecimal(Runtime.getRuntime().totalMemory());
//程序当前堆内存(兆)
BigDecimal totalMemoryM = totalMemoryByte.divide(new BigDecimal(1024*1024));
System.out.println("程序当前堆内存:"+totalMemoryM+"m");

//程序最大堆内存(字节)
BigDecimal maxMemoryByte = new BigDecimal(Runtime.getRuntime().maxMemory());
//程序最大堆内存(兆)
BigDecimal maxMemoryM = maxMemoryByte.divide(new BigDecimal(1024*1024));

System.out.println("程序最大堆内存:"+maxMemoryM+"m");
try {
Thread.sleep(1000000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

打印结果:
程序当前堆内存:9.5m
程序最大堆内存:9.5m

结果说明:
我设置的起始内存和最大内存为10m,但是Runtime取到的却是9.5m,因为Runtime取的堆内存是指可使用的堆内存,在年轻代中的
两个survivor只有一个会被正在使用(两个不会被同时使用).所以只算了一个survivor区,一个survivor区的大小是0.5m,所以
得到的大小是9.5m

<< · Back Index ·>>

发表回复

相关推荐

书信,让书法史有了温度——翻开古人的书信就像点开朋友圈

书信,让书法史有了温度 书论 文 | 书艺课堂 (ID: shuyiketang) 转载请联系授权 书友们,大家好,我是书艺君。今天和大家 ...

· 5秒前

看到蓮座狀的盆栽笹之雪,很少有看到後不動心的,養護略有難度

如果你喜歡龍舌蘭這種植物,那一定不要錯過笹之雪(Agave victoriae-reginae),它也叫皇後龍舌蘭或鬼腳掌(之前價格超貴,現...

· 7秒前

辦公小技巧:Word豎向求和

word豎向求和怎麼做?大傢都知道辦公軟件中一聽到求和二字都會想到excel表格,但其實辦公軟件中並非隻有excel才有表格,隻不...

· 14秒前

能推荐几个免费资源多的小说软件吗?

推荐10个用了半年多依旧稳定好用的小说APP,全部都完全免费,资源贼多,还支持导入书源!

· 24秒前

如何鍛煉背部肌肉

上回書說到:“外行看腹,新手看胸,高手看背,大師看腿”,胸已經給大傢講的差不多瞭,今天和大傢聊聊背。有系統練背想法的人...

· 33秒前