对象的内存分配,一般就是在堆上分配空间,对象主要分配在新生代的Eden区上,如果启动了本地线程分配缓冲,将按线程优先在TLAB(缓存)上分配。也可能会直接分配在老年代中,分配的规则并不是百分之百固定的,其细节取决于当前使用的是哪一种垃圾收集器组合,还有虚拟机中与内存相关的参数的设置。
1、对象优先在Eden分配
大多数情况下,对象在新生代Eden区中分配。当Eden区没有足够的空间进行分配时,虚拟机将发起一次Minor GC。
-xmn10M 为jvm的新生代空间;
-Xms20m -Xmx20m -Xmn10m -XX:+PrintGCDetails -XX:SurvivorRatio=8 -Xloggc:D:/Documents/gc.log
public static void main(String...s) throws Exception{ byte[] b1 = new byte[2 * 1024*1024]; byte[] b2 = new byte[2 * 1024*1024]; byte[] b3 = new byte[2 * 1024*1024]; byte[] b4 = new byte[4 * 1024*1024];//超过了10m }没有出现异常,查看gc日志:
0.082: [GC 0.082: [DefNew: 6692K->370K(9216K), 0.0028794 secs] 6692K->6514K(19456K), 0.0029189 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] Heap def new generation total 9216K, used 4794K [0x334f0000, 0x33ef0000, 0x33ef0000) eden space 8192K, 54% used [0x334f0000, 0x33941fa0, 0x33cf0000) from space 1024K, 36% used [0x33df0000, 0x33e4cb30, 0x33ef0000) to space 1024K, 0% used [0x33cf0000, 0x33cf0000, 0x33df0000) tenured generation total 10240K, used 6144K [0x33ef0000, 0x348f0000, 0x348f0000) the space 10240K, 60% used [0x33ef0000, 0x344f0030, 0x344f0200, 0x348f0000) compacting perm gen total 12288K, used 146K [0x348f0000, 0x354f0000, 0x388f0000) the space 12288K, 1% used [0x348f0000, 0x34914a68, 0x34914c00, 0x354f0000) ro space 10240K, 45% used [0x388f0000, 0x38d77290, 0x38d77400, 0x392f0000) rw space 12288K, 54% used [0x392f0000, 0x3997ace8, 0x3997ae00, 0x39ef0000)
分析:
new generation(新生代):
eden space 8192K = 10*1024kb *80%
form space(survival) = 1024kb ****这里可用的空间大小为9*1024kb****
to space(survival) = 1024kb
tenured generation(老年代):
space 10* 1024kb
执行main方法时,会发生minor gc 因为新生代需要的内存空间为10m而可用的空间是9m,而b1,b2,b3大小为2m比to space(1m)大,不能通过复制方法执行;此时gc只能通过担保机制将b1,b2,b3放入tenured generation中,这样新生代可用空间又为9m了;
1.the space 10240K, 60% used
2.eden space 8192K, 54% used
from space 1024K, 36% used
2、大对象直接进入老年代
大对象就是指需要大量连续内存空间的Java对象,典型大对象:长字符串及数组。大对象对虚拟机的内存分配来说就是一个坏消息(遇到一群“朝生夕灭”的“短命大对象”,写程序时应当避免),经常出现大对象容易导致内存还有不少空间时就提前触发垃圾收集以获取足够的连续空间来“安置”它们。
虚拟机提供了一个-XX:PretenureSizeThreshold=3*1024*1024参数,令大于这个设置值的对象直接在老年代中分配。这样做的目的是避免在Eden区及两个Survivor区之间发生大量的内存拷贝
PretenureSizeThreshold参数只对Serial和ParNew两款收集器有效,Parallel Scavenge收集器不认识这个参数,Parallel Scavenge收集器一般并不需要设置。如果遇到必须使用此参数的场合,可以考虑ParNew加CMS的收集器组合。
3、长期存活的对象将进入老年代
内存回收时应该识别哪些对象应当放在新生代,哪些对象应放在老年代中。为了做到这点,虚拟机给每个对象定义了一个对象年龄(Age)计数器。如果对象在Eden出生并经过第一次Minor GC后仍然存活,并且能被Survivor容纳的话,将被移动到Survivor空间中,并将对象年龄设为1。对象在Survivor区中每熬过一次Minor GC,年龄就增加1岁,当它的年龄增加到一定程度(默认为15岁)时,就会被晋升到老年代中。对象晋升老年代的年龄阈值,可以通过参数-XX:MaxTenuringThreshold=15来设置。
4、 动态对象年龄判定
为了能更好地适应不同程序的内存状况,虚拟机并不总是要求对象的年龄必须达到MaxTenuringThreshold才能晋升老年代,如果在Survivor空间中相同年龄所有对象大小的总和大于Survivor空间的一半,年龄大于或等于该年龄的对象就可以直接进入老年代,无须等到MaxTenuringThreshold中要求的年龄。
5、空间分配担保
在发生Minor GC时,虚拟机会检测之前每次晋升到老年代的平均大小是否大于老年代的剩余空间大小,如果大于,则改为直接进行一次Full GC。如果小于,则查看HandlePromotionFailure设置是否允许担保失败;如果允许,那只会进行Minor GC;如果不允许,则也要改为进行一次Full GC。大部分情况下都还是会将HandlePromotionFailure开关打开,避免Full GC过于频繁。
相关推荐
通过这次实验,我们了解到内存分配与回收策略对系统效率的影响。首次适应算法在快速分配内存上有优势,但可能导致大块内存被切割成小碎片;最佳适应算法则尽可能减少碎片,但可能在分配较大内存时造成不必要的搜索。...
### Java的内存管理机制分析 #### 一、Java内存区域划分 Java的内存管理机制将内存分为以下几个区域: 1. **栈(Stack)**: - 存储局部变量(如基本类型的变量和对象的引用)。 - 每个线程拥有一个独立的栈。 ...
Java虚拟机(JVM)内存分配机制和垃圾回收(Garbage Collection, GC)是Java编程中的核心概念,它们直接影响到程序的性能和稳定性。本文主要围绕JVM内存区域的分配策略,尤其是对象在新生代(Young Generation)的...
由于提供的文件信息中并没有包含实际的内容,我...开发者在编写应用时,也需要关注内存使用情况,合理使用内存资源,避免出现内存泄漏等问题,这样可以更好地与安卓系统的内存管理机制配合,提升应用性能和用户满意度。
内存分配与回收是操作系统中关键的功能,确保程序的高效运行和内存的合理利用。在本项目中,我们将探讨如何使用C语言来模拟这个过程。 C语言是一种底层编程语言,非常适合用于实现操作系统级别的功能。它提供了直接...
“win-virson”和“linux-virson”可能是模拟或实验代码,它们可能包含实现这些内存管理机制的伪代码或者实际可执行程序,帮助我们更好地理解和比较Windows与Linux的内存管理差异。 总的来说,这个项目提供了深入...
JVM 垃圾回收器是 Java 虚拟机(JVM)中的一种自动内存管理机制,用于回收无用的对象和释放内存空间。垃圾回收器的主要作用是减少内存泄露和提高应用程序的性能。 垃圾回收器的类型有多种,包括标记-清除算法、复制...
### 可变分区存储管理方式的内存分配与回收 #### 概述 可变分区存储管理方式是一种在早期操作系统中广泛采用的内存管理技术。它通过动态地将内存划分为不同大小的分区来满足不同程序的内存需求。这种方式能够有效地...
本文将详细介绍Spark内存管理机制,并探讨其优化的策略和实践。 首先,要了解Spark内存管理,先要区分Java堆内存和堆外内存。在Spark中,内存管理机制与JVM(Java虚拟机)有着紧密的联系。Java堆内存是JVM管理的...
操作系统中的内存管理是计算机系统设计的关键部分,它涉及到如何有效地分配、使用和回收内存资源,以确保多个进程的高效运行和系统的稳定...通过这次实习作业,你将有机会亲手实践这些理论,加深对内存管理机制的理解。
根据给定的文件信息,我们可以深入探讨操作系统中的内存分配与回收机制,特别是连续分配与分页式分配这两种常见的内存管理方式。以下是对标题、描述、标签以及部分内容中提及的知识点的详细阐述: ### 操作系统内存...
### 深入理解.NET内存回收机制 #### 一、引言 在.NET框架中,内存管理是一项核心功能,它负责自动地管理应用程序所使用...在未来的技术发展中,.NET将继续优化其内存管理机制,为开发者提供更加高效稳定的开发平台。
在“内存分配与回收设计”代码中,读者可以期待看到如何自定义内存分配器,如何实现智能指针,以及如何使用内存池来优化内存管理的示例。这些实践将帮助开发者更好地理解和掌握内存管理的艺术,避免在实际项目中出现...
Windows内存管理机制负责有效地分配、使用和回收系统资源,以确保程序的稳定运行。同时,C++作为一种强大的编程语言,其内存管理策略是程序员必须理解的核心概念。本文将深入探讨Windows内存管理机制以及C++中的内存...
在本实验中,我们将关注以页面为单位的虚拟内存分配方法,这通常用于现代操作系统,如Linux和Windows。虚拟内存允许程序使用比实际物理内存更大的地址空间,通过将不常用的数据交换到磁盘上,从而实现内存的高效利用...
### Python内存管理机制详解 #### 一、引言 Python作为一种高级动态语言,在运行时创建和销毁大量对象的过程中,内存管理扮演着至关重要的角色。它不仅直接影响到程序的执行效率,还关系到资源的合理利用。本文将...
总的来说,这个实验旨在通过实践加深对内存管理的理解,通过设计不同的分配策略和回收机制,分析其对系统性能的影响,这对于理解和优化操作系统的工作原理具有重要意义。在实际操作中,应注重程序的可读性和输出的...
内存分配和回收是操作系统管理计算机资源的核心任务之一,特别是在多任务环境下,有效管理内存对于系统的稳定性和性能至关重要。...这有助于培养对操作系统内存管理机制的深入理解,为未来的系统设计和优化打下基础。
### 可变分区存储管理方式的内存...通过合理的内存分配与回收策略,可以显著提升系统的性能并降低内存碎片的影响。此外,通过具体的C++程序代码,我们也更直观地理解了这些算法的工作原理及其在实际应用中的实现细节。
总之,Sun JDK 1.6的内存管理机制是其高效运行的基础,通过采用各种先进的分配与回收策略,以及引入如JRockit这样的高性能JVM,极大地提升了Java应用程序的执行效率和稳定性。理解这些内存管理的具体实现,对于深入...