内存管理

Java内存泄露

亡梦爱人 提交于 2020-04-06 19:15:39
一、概述 虽然Java有垃圾收集器帮助实现内存自动管理,虽然GC有效的处理了大部分内存,但是并不能完全保证内存的不泄露。 二、内存泄露 内存泄露就是堆内存中不再使用的对象,但是垃圾回收期无法从内存中删除他们的情况,因此他们会被不必要的一直存在。,这种情况会耗尽内存资源并降低系统性能,最终以OOM终止。 垃圾回收器会定期删除未引用的对象,但它永远不会收集那些仍在引用的对象。 内存泄露的症状: 应用程序长时间连续运行时性能严重下降; 应用程序中的OutOfMemoryError堆错误; 自发且奇怪的应用程序崩溃; 应用程序偶尔会耗尽连接对象。 三、Java中内存泄露类型 1、static字段引起的内存泄露 大量使用static字段会潜在的导致内存泄露,在Java中,静态字段通常拥有与整个应用程序相匹配的生命周期。 解决办法:最大限度的减少静态变量的使用;单例模式时,依赖于延迟加载对象而不是立即加载方式。 2、未关闭的资源导致内存泄露 每当创建连接或者打开流时,JVM都会为这些资源分配内存。如果没有关闭连接,会导致持续占有内存。在任意情况下,资源留下的开放连接都会消耗内存,如果我们不处理,就会降低性能,甚至OOM。 解决办法:使用finally块关闭资源;关闭资源的代码,不应该有异常;jdk1.7后,可以使用try-with-resource块。 3、不正确的equals(

Windows 内存管理

允我心安 提交于 2020-03-29 03:53:38
1 . Windows 的内存结构 Windows 系统中的每个进程都被赋予它自己的虚拟地址空间。对于 32 位进程来说,这个地址空间是 4GB ,因为 32 位指针可以拥有从 0x00000000 至 0xFFFFFFFF 之间的任何一个值。对于 64 位进程来说,则这个空间是 16EB 。由于每个进程可以接收它自己的私有的地址空间,因此当进程中的一个线程正在运行时,该线程也只能访问只属于它的进程的内存。属于所有其他进程的内存则隐藏着,并且不能被访问。 每个进程的虚拟地址空间都要划分成各个分区,地址空间的分区时根据操作系统的基本实现来进行的,不同的 windows 内核,其分区也略有不同。下面以 32 位 windows 2000 (x86 和 alpha 处理器 ) 分区 地址范围 作用 NULL 指针分配的区域 0x00000000 为了帮助掌握 NULL 指针的分配情况,任何读写都将引发访问违规 0x0000FFFF 用户方式分区 0x00010000 这是进程的私有空间,该分区是维护进程的大部分数据的地方。 0x7FFEFFFF 64k 禁止进入分区 0x7FFF0000 这个分区是禁止进入的,任何访问都将是违规。保留此分区是为了更加容易地实现操作系统。怕用户内存越界到内核区。 0x7FFFFFFF 内核方式 0x80000000 这个分区是存放操作系统代码的地方

Windows Embedded CE 6.0 Internals (3) Memory Continued

﹥>﹥吖頭↗ 提交于 2020-03-29 03:43:04
对我来说写一篇博客真的不容易,我是个十足的完美主义者,但是水平很一般,所以我会花上很多时间去修补文章。也许文章并不能让你满意,如果你有任何的建议,任何的,我都非常期待你能告诉我。这篇文章仍然是继续 Windows Embedded CE Internals (2) 内存部分。 从硬件视角看内存 从硬件上看,可作为内存的大体分为RAM、ROM、Nand/Nor Flash(兼具RAM和ROM特性的混合体)。 RAM 內存 可以进一步分为静态随机存取存储器( SRAM )和动态随机存取存储器( DRAM )两大类。 SRAM 具有快速访问的优点,但生产成本较为昂贵,一个典型的应用是 高速缓存 。而 DRAM 由于具有较低的单位容量价格,所以被大量的采用作为系统的 主存储器 。 以下简单列举一些RAM: DRAM SRAM VRAM(Video RAM) DDR SDRAM(Double Data Rate SDRAM) DDRII(Double Data Rate Synchronous DRAM) 那么RAM、ROM、Flash有哪些区别?我在这里简单的总结一下: 1.RAM需要供电才能保存数据,而ROM、Flash都不需要。 2.内存中的代码能够直接被执行的前提是CPU能够随机读取这个内存里面的数据,RAM满足这个条件的,还满足这个条件的是ROM和Nor Flash(也就是XIP)

linux内存寻址

爷,独闯天下 提交于 2020-03-28 22:33:30
本章节介绍linux寻址技术,详细描述80x86微处理器怎样进行芯片级的内存寻址,linux又是如何寻址硬件的。 1. linux内存地址   80x86微处理器下主要有三种不同的地址:逻辑地址,线性地址,物理地址。 逻辑地址:   主要用于兼容早起80x86处理(段式内存管理方式),包含在机器语言指令中用来指定一个操作数或一条指令的地址。每个逻辑地址由一个段标识符(segment)和一个偏移量(offset)组成,偏移量指明从段开始到实际地址之间的距离。段标识符是一个16bits的字段,成为段选择符(segment selector),而偏移量是一个32bits的字段。 线性地址:   也叫虚拟地址,和逻辑地址一样不是一个真实的地址,如果逻辑地址对应段式内存管理方式下转换前的地址,那么线性地址就是页式内存管理方式下转换前的地址。在32位处理器上,它是一个32为无符号整型,用于寻址4G,也就是高达4294967296个内存单元。 物理内存:   是内存芯片级的单元寻址,与微处理器上的地址引脚发送到内存总线上的电信号相对应,也就是我们常说的真实物理地址。 CPU内存管理单元(MMU)将一个逻辑地址转换到物理地址需要两步: (1).通过分段单元(segmentation unit)的硬件电路将逻辑地址转换成线性地址 (2).通过分页单元(paging unit

数据内存管理

家住魔仙堡 提交于 2020-03-28 06:24:41
根据用于分配内存的方法,C++提供了3种管理数据内存的方式:自动存储、静态存储和动态存储(也称自由存储空间或堆)。在存在时间的长短方面,以这3种方式分配的数据对象各不相同。 1、自动存储 在函数内部 定义的 常规变量使用自动存储空间,被称为自动变量,这意味着它们在所属的函数被调用时自动产生,在该函数结束时消亡。 实际上,自动变量是一个局部变量,其作用域为包含它的代码块。代码块是被包含在花括号中的一段代码。到目前为止,我们使用的所有代码块都是整个函数 。 如for循环函数、if条件判断函数(特别注意:if( ; ; ){…},容易忽略)。 函数内也可以有代码块,如果在其中的某个代码块定义一个变量,则该变量仅在程序执行该代码块中的代码时存在。 自动变量通常存储在栈中。这意味着执行代码块时,其中的变量将依次加入到栈中,而在离开代码块时,将按相反的顺序释放这些变量,这被称为后进先出。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。 2、静态存储 静态存储是整个程序执行期间都存在的存储方式。使变量称为静态的方式有两种:一种是在函数外面定义它;另一种是在声明变量时使用关键字static。 自动存储和静态存储的关键在于:这些方法严格限制了变量的寿命。 3、动态存储 new和delete运算符提供了一种比自动变量和静态变量更灵活的方法。它们管理一个内存池,这在C+

C内存管理

Deadly 提交于 2020-03-28 06:14:35
内存管理 将函数中命令、语句编译成相应序列的机器指令代码,放在代码段中; 将已初始化的数据,如已赋值的全局变量、静态局部变量等放在数据段内; 将未初始化的数据放在BSS段内; 将临时数据,如函数调用时传递的参数、局部变量、返回调用时的地址等放在栈段内; 而对一些动态变化的数据,如在程序执行中建立的一些数据结构,如链表、动态数组等放在堆结构中。 Malloc()和free()来分配和释放内存 PC机存储器分为主存储器、外存储器和高速缓存(Cache)几个部分 堆是一种动态存储的结构,实际上就是数据段中的自由存储区,他是C语言中使用的一中名称,常常用于动态数据结构存储分配。 堆管理函数: Malloc() free() realloc() calloc() malloc() void *malloc( unsigned size ); 向系统申请分配指定size个字节的内村空间,返回类型是void类型。 int *p; p = ( int * ) malloc ( sizeof(int) ); 例程: #include< stdio.h > #include< stdlib.h > main() { char *str; if( ( str = (char *)malloc(50)) == NULL ) { printf( "\n No enough memory to

内存管理之堆

依然范特西╮ 提交于 2020-03-28 05:56:28
内存管理之堆 什么是堆 堆(heap)是一种内存管理方式。内存管理对操作系统来说是一件非常复杂的事情,因为首先内存容量很大,其次内存需求在时间和大小块上没有规律(操作系统上运行着的几十、几百、几千个进程随时都会电请或者释放内存,申请或者释放的内存块大小随意) 堆这种内存管理方式特点就是自由(随时申请、释放、大小块随意)。堆内存是操作系统划归给堆管理器(操作系统中的一段代码,属于操作系统的内存管理单元)来管理的,然后向使用者(用户进程)提供API (malloc和free)来使用堆内存。 我们什么时候使用堆内存?需要内存容量比较大时,需要反复使用及释放时,很多数据结构(譬如链表)的实现都要使用堆内存。 堆管理内存的特点 (大块内存、手工分配&使用&释放) 特点一容量不限(常规使用的需求容量都能满足) 特点二:申请及释放都需要手工进行,手工进行的含义就是需要程序员写代码明确进行申请malloc及释放free。如果程序员申请内存并使用后未释放,这段内存就丢失了(在堆管理器的记录中,这段内存仍然属于你这个进程,但是进程自己又以为这段内存已经不用了,再用的时候又会去申请新的内存块,这就叫吃内存),称为内存泄漏。在C/C++语言中,内存泄漏是最严重的程序bug,这也是别人认为Java/C#等语言比c/C+ +优秀的地方。 c语言操作堆内存的接口 (malloc free) 堆内存释放时最简单

内存管理之堆heap

こ雲淡風輕ζ 提交于 2020-03-28 05:55:56
1、什么是堆? 堆(heap)是一种内存管理方式。内存管理对操作系统来说是一件非常复杂的事情,因为首先内存容量很大, 其次就是内存需求在时间和大小块上没有规律(操作系统上运行着几十甚至几百个进程,这些进程可能随时 都会申请或者是释放内存,并且申请和释放的内存块大小是随意的)。 堆这种内存管理方式的特点就是自由(随时申请、随时释放、大小块随意)。堆内存是操作系统划归给堆管 理器(操作系统中的一段代码,属于操作系统的内存管理单元)来管理的,然后向使用者(用户进程)提供 API(malloc和free)来使用堆内存。 我们什么时候使用堆内存? 当我们需要的内存容量比较大时,需要反复使用及释放时,很多数据结构(譬如链表)的实现都要使用堆内存。 2、堆管理内存的特点(大块内存、手工分配&使用&释放) 特点一:容量不限(常规使用的需求容量都可以满足) 特点二:申请及释放都需要手工运行,手工进行的含义就是需要程序员写代码明确进行申请malloc及释放free。 如果程序员申请内存并使用后未释放,这段内存就丢失了(在堆管理器的记录中,这段内存仍然属于你这个进程, 但是进程自己又以为这段内存已经不用了,所以进程再次运行的时候,就又会去申请新的内存块,这就叫做吃内存), 称之为内存泄漏。在C/C++语言中,内存泄漏是最严重的程序bug,这也是别人认为Java/C#等语言比C/C++优秀的地方。 3

动态内存管理

自闭症网瘾萝莉.ら 提交于 2020-03-28 05:53:46
(1).c中动态内存管理方式 malloc、calloc、realloc在堆上开辟空间、free将申请的空间释放掉 void *malloc( size_t size ); void *calloc( size_t num , size_t size ); void *realloc( void * memblock , size_t size ); (2).C++中动态内存管理 通过new和delete运算符进行动态内存管理 (3).malloc/free和new/delete的区别与联系 a.它们都是动态管理内存的的入口 b.malloc/free只是动态的分配和释放内存空间。new/delete除了分配空间还会调用构造函数和析构函数进行初始化与清理(清理成员) c.malloc需要手动的计算类型大小并且返回值是void*。new可自己计算类型的大小,返回对应类型的指针 (4).new[]和delete[] new[]/delete[]只是malloc/free的一层封装,不会调用对象的构造函数/析构函数,来初始化/清理对象 new的作用:调用operator new来分配空间,调用构造函数初始化对象 delete的作用:调用析构函数清理对象,调用operator delete释放空间 new[]的作用:调用operator new分配空间,调用N次构造函数来初始化对象

内存管理

主宰稳场 提交于 2020-03-21 19:46:18
不光还是游戏引擎,任何一个项目都有必要做好内存管理,至少可以监控内存使用量和内存泄露。而对于游戏引擎而言更是如此,在游戏引擎里面动态分配释放内存的地方不在少数,做好内存管理对于提高引擎运行效率是十分必要的。 内存管理就是做两件事,负责内存的分配和释放,再有就是对内存的分配释放进行监控,据此来解决内存泄露和掌握内存使用情况。 先说说内存分配释放,这也是内存管理最重要的部分。一般来说内存管理只管理小内存的分配释放,大内存则无需管理制作监控即可。过多的小内存分配释放会造成系统内存碎片从而可能分配不下内存,与此同时过多的调用系统的内存分配释放函数也是低效。malloc,free这些函数本身就很慢。 现在问题的本质出来了,内存管理关的就是小内存的分配释放,要采用某种办法避免经常性的调用系统的分配释放函数,简单来说就是要解决这个问题。具体办法是这样的,以Unreal的内存管办法为例,他认为32k以下的内存都是小内存,>32k的不作管理。当申请size大小的内存时他一次性分配64k,这样就获得了64k/size个内存块,这就是一个池,当再次分配同样大小的内存时则从这个池中取不仅新真正的内存分配,当池满了则在分配64k以同样的方法管理,当池空了的时候释放这64k的内存。可以看出他的内存分配单位是64k,且只有在池满了或者池空后才做真正的内存分配释放。 再说说内存监控,这一块可发挥的空间非常大