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

jvm堆内存

  • 内存
  • 2024-06-13 07:47:24
  • 1121

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

1:堆内存和非堆内存的定义
Java虚拟机有一个堆(heap)。。堆是在Java虚拟机启动时创建的。在JVM中,堆外的内存就变成了非堆内存(Non-heapmemory)。
内存及相应的垃圾收集算法
1堆的大小是可以扩大和缩小的。
2.对象创建后进入Eden。年轻代分为Eden和Survivor。Survivor由FromSpace和ToSpace组成。Eden区占据大容量,Survivor区占据小容量。默认比例为8:1:1。
MinorGC:使用复制算法。首先将Eden区和ServivorFrom区中存活的对象分配到ServivorTo区(如果对象年龄达到年龄标准/ServivorTo位置不够,则复制到老年代),同时对象年龄为+1,然后删除Eden和ServivorFrom中的对象。然后,ServivorTo和ServivorFrom被交换。
3.老年代
老年代存储的是生命周期较长的内存对象。
老年代对象相对稳定,不会经常发生GC。在MajorGC之前,通常先进行MinorGC,使新生代的对象进入老年代,只有在空间不足时才会触发。当足够大的连续空间无法分配给新对象时,会提前触发MajorGC进行垃圾回收。
MajorGC:如果使用CMS收集器,请使用标记-清除算法。首先扫描老年代,标记所有可回收的物品,标记完成后,所有标记的物品都会被均匀回收。同时,会产生不连续的内存碎片。过多的碎片会导致程序以后需要分配较大的对象时无法找到足够的连续内存,需要重新启动GC。否则,使用标记压缩算法。
标签压缩:标记可回收物品后,将不可回收物品移至一端,然后删除已标记的物品。
当老年代已满,无法加载时,抛出OOM异常。
二:永久代
永久存储在内存中的区域主要存储类和元数据(metadata)类在加载时就被放置在永久区域中。与存储实例的区域不同,GC在主程序执行期间不会清理永久区域。因此,随着加载的类越多,也会导致永久生成区变满,从而引发OOM。
在Java8中,永久代已经被移除,取而代之的是一个叫做“元数据区”(metaspace)的区域。
元空间的核心与永久代类似,都是JVM方法空间的实现。然而,Metaspace使用本地内存,永久代位于JVM虚拟机中。因此,默认情况下,元空间的大受到本地内存的限制。类的元数据放在native内存中,类的字符串常量池和静态变量放在Java堆中。这样,可以加载多少个类的元数据就不是由MaxPermSize控制,而是由.系统的实际可用空间。
1Metaspace修复了永久代的OOM问题。元数据和类对象在永久代中容易出现性能问题和内存溢出。
难以确定2类方法信息的大小等,难以指定永久代的大小。
3永久代会给GC带来不必要的复杂性,回收效率低。
三:堆内存参数调优
1.-Xms设置初始分配内存大小,默认物理内存为1/64
2.-Xmx设置最大分配内存,默认物理内存内存为1/4longmaxMemory=time().maxMemory();longtotalMemory=time().totalMemory();n("最大分配内存"+maxMemory/(double)1024/1024+"MB"+maxMemory/(double)1024/1024/1024+"GB");n("默认分配内存"+totalMemory/(double)1024/1024+"MB"+totalMemory/(双)1024/1024/1024+"GB");