当前位置:首页 > 内存 > 正文

java jvm内存模型

  • 内存
  • 2024-06-11 01:51:07
  • 5751

一、jvm堆内存和非堆内存(小白入门文,各博客视频基础总结)

1:堆内存和非堆内存的定义
Java虚拟机有一个堆。堆是运行时数据区域,所有类实例和数组的内存都在其中分配。。堆是在Java虚拟机(JVM)启动时创建的。在JVM中,堆之外的内存是非堆内存。
堆内存及其垃圾回收算法
1.堆的大小可以是固定的,也可以增长和收缩。堆内存不需要是连续的空间。
2.对象创建后,就进入Eden。年轻代分为Eden代和Survivor代。幸存者由FromSpace和ToSpace组成。Eden区占用的容量较大,Survivor区占用的容量较小。默认比例为8:1:1。
MinorGC:使用复制算法。首先将Eden区和ServivorFrom区幸存的对象分配到ServivorTo区(如果对象年龄达到老年代标准或者ServivorTo位置不足,则复制到OldGeneration),同时将对象复制到OldGeneration区年龄已指定。按+1,然后清除Eden和ServivorFrom中的对象。然后交换ServivorTo和ServivorFrom。
3.老年代
老年代存储的是生命周期较长的内存对象。
OldGeneration对象相对稳定,因此GC不会频繁发生。MinorGC通常先于MajorGC执行,因此只有当新生代对象进入Old代并且空间即将耗尽时才会触发。如果找不到足够大的连续空间来分配新对象,MajorGC就会预先触发进行垃圾回收。
MajorGC:如果使用CMS收集器,请使用标记清除算法。首先,它扫描老一代并显示所有可回收对象。一旦标记完成,所有标记的对象都会被统一回收。同时,不连续的内存碎片被创建。如果碎片过多,当程序稍后需要分配较大的对象时,将无法找到足够的连续内存,GC将不得不重新启动。否则使用标记压缩算法。
标记压缩:对可回收物品进行标记后,将不可回收物品移至一端,并擦除标记的物品。
如果上一代已满而无法加载,则会引发OOM异常。
二:永久创建
永久存储在内存中的区域主要存储类和meta(元数据)信息,当一个类被加载时,就会被放入持久化区域。与存储实例的区域不同,GC在主程序执行期间不会清理持久区域。因此,随着加载的类越多,持久代区可能会变满,从而导致OOM。
在Java8中,持久化创建被移除,取而代之的是一个称为“元数据区域”(metaspace)的区域。
元空间的本质与持久化创建类似,都实现了JVM方法区。然而,元空间使用本地内存,持久化创建驻留在JVM虚拟机中。所以基本上,元空间的大小受到本地内存的限制。类的元数据放置在本机内存中,类的字符串常量池和静态变量放置在Java堆中。这样,关于可以加载多少个类的元数据就不再受MaxPermSize控制。系统上的实际可用空间。
1Metaspace解决了持久化创建的OOM问题。元数据和类对象在持久化创建时容易出现性能问题和内存溢出。
类型2方法信息的大小等很难确定。很难指定永久代的大小。小的永久代溢出,大的老年代溢出。
3永久代给GC带来了不必要的复杂性,降低了回收效率。
3:调优堆内存参数
1.-Xms设置初始分配内存大小,默认物理内存为1/64。
2.-Xmx设置最大分配内存,默认物理内存为1/4内存
longmaxMemory=time().maxMemory();longtotalMemory=time().totalMemory();n("最大分配内存"+maxMemory/(double)1024/1024+"MB"+maxMemory/(double)1024/1024/1024+"GB");n("默认分配内存"+totalMemory/(double)1024/1024+"MB"+总内存/(双)1024/1024/1024+"GB");