堆内存

JVM实用参数(四)内存调优

混江龙づ霸主 提交于 2020-04-08 13:15:35
理想的情况下,一个Java程序使用JVM的默认设置也可以运行得很好,所以一般来说,没有必要设置任何JVM参数。然而,由于一些性能问题(很不幸的是,这些问题经常出现),一些相关的JVM参数知识会是我们工作中得好伙伴。在这篇文章中,我们将介绍一些关于JVM内存管理的参数。知道并理解这些参数,将对开发者和运维人员很有帮助。 所有已制定的HotSpot内存管理和垃圾回收算法都基于一个相同的堆内存划分:新生代(young generation)里存储着新分配的和较年轻的对象,老年代(old generation)里存储着长寿的对象。在此之外,永久代(permanent generation)存储着那些需要伴随整个JVM生命周期的对象,比如,已加载的对象的类定义或者String对象内部Cache。接下来,我们将假设堆内存是按照新生代、老年代和永久代这一经典策略划分的。然而,其他的一些堆内存划分策略也是可行的,一个突出的例子就是新的G1垃圾回收器,它模糊了新生代和老年代之间的区别。此外,目前的开发进程似乎表明在未来的HotSpot JVM版本中,将不会区分老年代和永久代。 -Xms and -Xmx (or: -XX:InitialHeapSize and -XX:MaxHeapSize) -Xms和-Xmx可以说是最流行的JVM参数,它们可以允许我们指定JVM的初始和最大堆内存大小。一般来说

堆内存溢出、栈内存溢出、栈溢出笔记

与世无争的帅哥 提交于 2020-04-08 10:56:14
堆内存溢出:堆内存放的都是对象,当引用对象占用内存超过分配的堆内存就会发生堆内存溢出。比如,堆分配1M内存,但是一个List中存放2M就会发生堆内存溢出。 栈内存溢出:栈内存溢出是指,分配的栈内存不够使用,导致栈内存溢出。比如多线程访问,每一个线程都会分配一个栈空间,如果线程足够多,分配的栈内存空间自然也会多,发生栈内存溢出。 栈溢出:栈溢出是指在压栈的过程中超出栈的深度,每调用一个方法都会进行压栈操作。当调用方法非常多时,导致超出栈的深度发生栈溢出,比如递归方法。 来源: oschina 链接: https://my.oschina.net/uwith/blog/3224474

.NET中栈和堆的比较(四)

故事扮演 提交于 2020-03-28 05:59:28
终于翻完了第四篇,本来每次都是周末发的,可惜上周末有些事儿没忙过来,所以今天中午给补上来。不知道这套文章还能不能继续了,因为作者也只写到了第四篇,连他都不知道第五篇什么时候出得来... 原文出处 http://www.c-sharpcorner.com/UploadFile/rmcochran/csharp_memory_401282006141834PM/csharp_memory_4.aspx 可以参看该系列文章的前面部分内容: Part I http://agassi001.cnblogs.com/archive/2006/05/10/396574.html Part II http://agassi001.cnblogs.com/archive/2006/05/13/399080.html Part III http://www.cnblogs.com/agassi001/archive/2006/05/20/405018.html 尽管在.NET framework下我们并不需要担心内存管理和垃圾回收(Garbage Collection),但是我们还是应该了解它们,以优化我们的应用程序。同时,还需要具备一些基础的内存管理工作机制的知识,这样能够有助于解释我们日常程序编写中的变量的行为。在本文中我们将深入理解垃圾回收器,还有如何利用静态类成员来使我们的应用程序更高效。 *

内存管理之堆

依然范特西╮ 提交于 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:55:27
1、堆内存   堆内存是由程序员手工管理的,但它的申请是需要借助标准库函数。在大小上,理论上是物理内存的大小。关于堆内存的数据保存是靠程序员来管理的。由于是由程序员管理的,程序员的错误操作也导致内存的泄露和内存碎片的问题。   关于堆内存的标准库函数(stdlib.h/malloc.h)   void* malloc(size_t size);   //size是以字节为单位   //返回值是所申请到的内存的首地址   //void* 不能直接使用,需要转换成其他有意义的才能使用。   //在大多数情况下void*可以自转换成任意类型,但在个别情况下需要使用强制类型转换   //malloc函数申请的内存,内容其实是随机的,需要通过那个bzero函数来将它清理为0;   void bzero(void* s,size_t n); //功能是把内存清理为0,以字节为单位 //s是内存首地址,n字节数    void* calloc(size_t nmemb,size_t size); //size是所申请内存的字节数,nmemb是申请多次size,所申请到的内存内容已经被清理为0;   void* realloc(void* ptr,size_t size); //调整已经有内存的大小,可把内存调大或调小。 //ptr是已有的内存首地址,size是调整后的大小。 /

C++栈和堆的生长方向

橙三吉。 提交于 2020-03-27 21:29:15
C++内存区域 分为5个区域。分别是堆,栈,自由存储区,全局/静态存储区和常量存储区。 栈 :由编译器在需要的时候分配,在不需要的时候自动清除的变量存储区。里面通常是局部变量,函数参数等。 堆 :由new分配的内存块,他们的释放编译器不去管,由我们的应用程序去控制,一般一个new对应一个delete。如果程序员没有释放掉,那么在程序结束后, 操作系统 会自动回收。 自由存储区 :由malloc等分配的内存块,和堆十分相似,不过它使用free来结束自己的生命。 全局/静态存储区 :全局变量和静态变量被分配到同一块内存中,在以前的c语言中。全局变量又分为初始化的和未初始化的,在c++里面没有这个区分了,他们共同占用同一块内存。 常量存储区 :这是一块比较特殊的存储区,里面存放的是常量,不允许修改。 C++内存区域中堆和栈的区别 : 管理方式不同 :栈是由编译器自动管理,无需我们手工控制;对于堆来说,释放由程序员完成,容易产生内存泄漏。 空间大小不同 :一般来讲,在32为系统下面,堆内存可达到4G的空间,从这个角度来看堆内存几乎是没有什么限制的。但是对于栈来讲,一般都是有一定空间大小的,例如,在vc6下面,默认的栈大小好像是1M。当然,也可以自己修改:打开工程。 project-->setting-->link,在category中选中output

判断栈和堆的生长方向

旧时模样 提交于 2020-03-27 21:22:15
如何判断栈的增长方向? 对于一个用惯了i386系列机器的人来说,这似乎是一个无聊的问题,因为栈就是从高地址向低地址增长。不过,显然这不是这个问题的目的,既然把这个问题拿出来,问的就不只是i386系列的机器,跨硬件平台是这个问题的首先要考虑到的因素。 在一个物质极大丰富的年代,除非无路可退,否则我们坚决不会使用汇编去解决问题,而对于这种有系统编程味道的问题,C是一个不错的选择。那接下来的问题就是如何用C去解决这个问题。 C在哪里会用到栈呢?稍微了解一点C的人都会立刻给出答案,没错,函数。我们知道,局部变量都存在于栈之中。似乎这个问题立刻就得到了解答,用一个函数声明两个局部变量,然后比较两个变量的地址,这样就可以得到答案。 等一下,怎么比较两个变量的地址呢? 先声明的先入栈, 所以,它的第一个变量的地址如果是高的,那就是从上向下增长。“先声明的先入栈”?这个结论从何而来?一般编译器都会这么处理。要是不 一般呢?这种看似正确的方法实际上是依赖于编译器的,所以,可移植性受到了挑战。 那就函数加个参数,比较参数和局部变量的位置,参数肯定先入栈。那为什么不能局部变量先入栈?第一反应是怎么可能,但仔细想来又没有什么不可以。所以,这种方法也依赖于编译器的实现。 那到底什么才不依赖于编译器呢? 不妨回想一下,函数如何调用。执行一个函数时,这个函数的相关信息都会出现栈之中,比如参数、返回地址和局部变量

堆和栈的区别(转过无数次的文章)

这一生的挚爱 提交于 2020-03-23 11:08:04
一、预备知识—程序的内存分配 一个由C/C++编译的程序占用的内存分为以下几个部分 1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其 操作方式类似于数据结构中的栈。 2、堆区(heap) — 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回 收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表,呵呵。 3、全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的 全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另 一块区域。 - 程序结束后由系统释放。 4、文字常量区 —常量字符串就是放在这里的。 程序结束后由系统释放 5、程序代码区—存放函数体的二进制代码。 二、例子程序 这是一个前辈写的,非常详细 //main.cpp int a = 0; 全局初始化区 char *p1; 全局未初始化区 main() { int b; 栈 char s[] = "abc"; 栈 char *p2; 栈 char *p3 = "123456"; 123456/0在常量区,p3在栈上。 static int c =0; 全局(静态)初始化区 p1 = (char *)malloc(10); p2 = (char *)malloc(20); 分配得来得10和20字节的区域就在堆区。

不可思议的OOM

无人久伴 提交于 2020-03-22 03:10:17
本文发现了一类OOM(OutOfMemoryError),这类OOM的特点是崩溃时java堆内存和设备物理内存都充足,下文将带你探索并解释这类OOM抛出的原因。 关键词: OutOfMemoryError, OOM,pthread_create failede, Could not allocate JNI Env 一、引子 对于每一个移动开发者,内存是都需要小心使用的资源,而线上出现的 OOM(OutOfMemoryError)都会让开发者抓狂,因为我们通常仰仗的直观的堆栈信息对于定位这种问题通常帮助不大。网上有很多资料教我们如何“紧衣缩食“的利用宝贵的堆内存(比如,使用小图片,bitmap 复用等),可是: 线上的 OOM 真的全是由于堆内存紧张导致的吗? 有没有 App 堆内存宽裕,设备物理内存也宽裕的情况下发生 OOM 的可能? 内存充裕的时候出现 OOM 崩溃? 看似不可思议,然而,最近笔者在调查一个问题的时候,通过自研的 APM 平台发现公司的一个产品的大部分 OOM 确实有这样的特征,即: OOM 崩溃时,java 堆内存远远低于 Android 虚拟机设定的上限,并且物理内存充足,SD 卡空间充足 既然内存充足,这时候为什么会有 OOM 崩溃呢? 二、问题描述 在详细描述问题之前,先弄清楚一个问题: 什么导致了 OOM 的产生? 下面是几个关于 Android