堆内存

堆外内存初探

被刻印的时光 ゝ 提交于 2019-11-27 16:08:22
使用Java语言的同学们都知道, Java的虚拟机对内存的管理大部分情况下就是指堆内存的管理, GC的也是对堆内存的清理和回收. 下面就看一下堆外内存的对JVM的意义. 第一次了解到堆外内存的使用场景是在使用netty, netty中提到的一个概念, "零拷贝", 也是netty高性能的原因之一. 零拷贝, 主要体现在三个方面: Netty的接收和发送ByteBuffer采用DIRECT BUFFERS,使用堆外(直接)内存进行Socket读写,不需要进行字节缓冲区的二次拷贝。如果使用传统的堆内存(HEAP BUFFERS)进行Socket读写,JVM会将堆内Buffer拷贝一份到直接内存中,然后才写入Socket中。相比于堆外直接内存,消息在发送过程中多了一次缓冲区的内存拷贝。 Netty提供了组合Buffer对象,可以聚合多个ByteBuffer对象,用户可以像操作一个Buffer那样方便的对组合Buffer进行操作,避免了传统通过内存拷贝的方式将几个小Buffer合并成一个大的Buffer。 Netty的文件传输采用了transferTo方法,它可以直接将文件缓冲区的数据发送到目标Channel,避免了传统通过循环write方式导致的内存拷贝问题。 在使用堆外内存的同时也带来了新的问题, 相比较堆内存, 堆外内存的分配和回收要更耗时, 所以netty提供了

堆和栈的区别

风流意气都作罢 提交于 2019-11-27 15:24:59
一、预备知识—程序的内存分配 一个由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);

成为Java GC专家(5)—Java性能调优原则

南笙酒味 提交于 2019-11-27 12:34:58
这是“ 成为Java GC专家 ”系列的第五篇文章。在第一篇 深入浅出Java垃圾回收机制 中,我们已经学习了不同的GC算法流程、GC的工作原理、新生代(Young Generation)和老年代(Old Generation)的概念。你应该了解了JDK7中5种GC类型以及各种类型对应用程序的影响。 在第二篇 如何监控Java的垃圾回收 中,阐述了 JVM 是怎样实际执行垃圾回收的,我们怎样去监控GC以及哪些工具能让这个过程更高效。 第三篇 如何如何优化Java垃圾回收机制 中展示了一些基于真实案例的最佳实践。同时讲解了怎样尽量少地将对象放入老年代空间(Old Area),避免频繁地执行完全垃圾回收(Full GC)。还说明了如何设置GC的类型和内存大小。 在第四篇 Apache的MaxClients参数详解及其在Tomcat执行FullGC时的影响 中,解释了MaxClients参数的重要性以及它在垃圾回收过程中对整个系统性能的显著影响。 第五篇文章将讲解Java程序性能调优的原则,尤其是在这个过程中必要的知识以及判断你的程序是否需要调优。还会介绍调优过程中你可能遇到的问题。本文最后会给出一些建议,依据这些你能在对Java程序调优时做出更好的决策。 概述 并不是每个程序都需要调优。如果一个程序性能表现和预期一样,你不必付出额外的精力去提高它的性能。然而,在程序调试完成之后

c++中关于堆和堆栈的区别

ε祈祈猫儿з 提交于 2019-11-27 11:24:49
在C++中,内存分成5个区,他们分别是堆、栈、自由存储区、全局/静态存储区和常量存储区。 栈,就是那些由编译器在需要的时候分配,在不需要的时候自动清楚的变量 的存储区。里面的变量通常是局部变量、函数参数等。 堆,就是那些由new分配的内存块,他们的释放编译器不去管,由我们的应 用程序去控制,一般一个new就要对应一个delete。如果程序员没有释放掉, 那么在程序结束后,操作系统会自动回收。 自由存储区,就是那些由malloc等分配的内存块,他和堆是十分相似的, 不过它是用free来结束自己的生命的。 全局/静态存储区,全局变量和静态变量被分配到同一块内存中,在以前的 C语言中,全局变量又分为初始化的和未初始化的(初始化的全局变量和静态变 量在一块区域,未初始化的全局变量与静态变量在相邻的另一块区域,同时未被 初始化的对象存储区可以通过void*来访问和操纵,程序结束后由系统自行释 放),在C++里面没有这个区分了,他们共同占用同一块内存区。 常量存储区,这是一块比较特殊的存储区,他们里面存放的是常量,不允许 修改(当然,你要通过非正当手段也可以修改,而且方法很多) 堆和栈究竟有什么区别? 主要的区别由以下几点: 1、管理方式不同; 2、空间大小不同; 3、能否产生碎片不同; 4、生长方向不同; 5、分配方式不同; 6、分配效率不同; 管理方式:对于栈来讲,是由编译器自动管理

java 堆与栈的区别

你离开我真会死。 提交于 2019-11-27 11:21:55
1.栈内存存储的是局部变量而堆内存存储的是实体; 2.栈内存的更新速度要快于堆内存,因为局部变量的生命周期很短; 3.栈内存存放的变量生命周期一旦结束就会被释放,而堆内存存放的实体会被垃圾回收机制不定时的回收。 来源: https://www.cnblogs.com/sea-stream/p/11361453.html

equals和==

不想你离开。 提交于 2019-11-27 10:34:02
1.java中==的含义 基本数据类型:byte,short,char,int,long,float,double,boolean     在java中对于基本数据类型比较的是他们值,应用双等号(==) 引用数据类型:当他们进行==的比较时,比较的是他们在堆内存中的地址。   所以对于此类型,通常不是一起new出来的对象比较结果都为false,因为每new一次,都会重新开辟堆内存空间。 2.equals()方法介绍 java中所有的类都是继承自Object 在Object类中定义了一个equals方法,这个方法是比较对象的内存地址,所以一般为了比较对象的属性都会重写equals()方法 来源: https://www.cnblogs.com/lsswudi/p/11359783.html

JVM调优总结

ぃ、小莉子 提交于 2019-11-27 07:36:42
1. jdk1.7的堆内存       1. 堆(Java堆)   堆是java虚拟机所管理的内存中最大的一块内存区域,也是被各个线程共享的内存区域,  在JVM启动时创建,该内存区域存放了对象实例(包括基本类型的变量及其值)及数组(所有new的对象)。  但是并不是所有的对象都在堆上,由于栈上分配和标量替换,导致有些对象不在堆上。   其大小通过-Xms(最小值)和-Xmx(最大值)参数设置,  1. -Xms为JVM启动时申请的最小内存,默认为操作系统物理内存的1/64但小于1G,  2. -Xmx为JVM可申请的最大内存,默认为物理内存的1/4但小于1G,  3. 默认当空余堆内存小于40%时,JVM会增大Heap到-Xmx指定的大小,可通过-XX:MinHeapFreeRation 来指定这个比列;  4. 当空余堆内存大于70%时,JVM会减小heap的大小到-Xms指定的大小,可通过XX:MaxHeapFreeRation来指定这个比例,  5. 对于运行系统,为避免在运行时频繁调整Heap的大小,通常-Xms与-Xmx的值设成一样。   由于现在收集器都是采用分代收集算法,堆被划分为新生代和老年代。  新生代主要存储新创建的对象和尚未进入老年代的对象。  老年代存储经过多次新生代GC(Minor GC)仍然存活的对象。   堆中没有足够的内存完成实例分配

java.lang.OutOfMemoryError:GC overhead limit exceeded

偶尔善良 提交于 2019-11-27 07:26:16
一旦被占用的内存空间不符合释放的条件,GC没办法清理,那就会适时出现 java.lang.OutOfMemoryError 。这个错误就是提醒我们这群程序猿,写GC程序的程序猿不知道这种情况怎么处理,为了安全也不便处理,谁使用Java就自己看着解决吧。 说起来, java.lang.OutOfMemoryError 有几种分类的,这次碰到的是 java.lang.OutOfMemoryError: GC overhead limit exceeded ,下面就来说说这种类型的内存溢出。 简单来说, java.lang.OutOfMemoryError: GC overhead limit exceeded 发生的原因是,当前已经没有可用内存,经过多次GC之后仍然没能有效释放内存。 1. 原因 众所周知,JVM的GC过程会因为STW,只不过停顿短到不容易感知。当引起停顿时间的98%都是在进行GC,但是结果只能得到小于2%的堆内存恢复时,就会抛出 java.lang.OutOfMemoryError: GC overhead limit exceeded 这个错误。 Plumbr 给出一个示意图: 3. 解决方法 3.1 JVM参数 JVM给出一个参数避免这个错误: -XX:-UseGCOverheadLimit 。 但是,这个参数并不是解决了内存不足的问题,只是将错误发生时间延后

JVM内存模型及垃圾收集策略解析

拈花ヽ惹草 提交于 2019-11-27 07:19:52
AD: JVM内存模型是Java的核心技术之一,之前51CTO曾为大家介绍过 JVM分代垃圾回收策略的基础概念 ,现在很多编程语言都引入了类似Java JVM的内存模型和垃圾收集器的机制,下面我们将主要针对Java中的JVM内存模型及垃圾收集的具体策略进行综合的分析。 一 JVM内存模型 1.1 Java栈 Java栈是与每一个线程关联的,JVM在创建每一个线程的时候,会分配一定的栈空间给线程。它主要用来存储线程执行过程中的局部变量,方法的返回值,以及方法调用上下文。栈空间随着线程的终止而释放。StackOverflowError:如果在线程执行的过程中,栈空间不够用,那么JVM就会抛出此异常,这种情况一般是死递归造成的。 1.2 堆 Java中堆是由所有的线程共享的一块内存区域,堆用来保存各种JAVA对象,比如数组,线程对象等。 1.2.1 Generation JVM堆一般又可以分为以下三部分: ◆ Perm Perm代主要保存class,method,filed对象,这部门的空间一般不会溢出,除非一次性加载了很多的类,不过在涉及到热部署的应用服务器的时候,有时候会遇到java.lang.OutOfMemoryError : PermGen space 的错误,造成这个错误的很大原因就有可能是每次都重新部署,但是重新部署后,类的class没有被卸载掉

什么是堆什么是栈

只谈情不闲聊 提交于 2019-11-27 02:40:33
一 英文名称 堆和栈是C/C++编程中经常遇到的两个基本概念。先看一下它们的英文表示: 堆――heap 栈――stack 二 从数据结构和系统两个层次理解 在具体的C/C++编程框架中,这两个概念并不是并行的。深入到汇编级进行研究就会发现,栈是机器系统提供的数据结构,而堆是由C/C++函数库提供的。这两个概念可以从数据结构和系统两个层次去理解: 1、从数据结构层次理解,栈是一种先进后出的线性表,只要符合先进后出的原则的线性表都是栈。至于采用的存储方式(实现方式)是顺序存储(顺序栈)还是链式存储(链式栈)是没有关系的。堆则是二叉树的一种,有最大堆最小堆,排序算法中有常用的堆排序。 2、从系统层次理解,栈是系统为运行的程序分配的先进后出的存储区域。在学习bootloader时知道,在上电后初始化阶段要为各个工作模式下分配堆 栈,这里的堆栈实际上就是指stack,堆栈的说法只是因为历史的原因。在执行函数时,函数内部局部变量的存储单元可以在栈上创建(针对CISC架构而 言,RISC架构下,局部变量的存储单元是在寄存器上创建),函数执行结束时这些存储单元自动被释放。堆是系统管理的可以被程序利用的全局存储空间,动态 内存分配就是从堆上分配。 具体地说,现在计算机(串行执行机制),都直接在代码层次支持栈这种数据结构。这体现在,有专门的寄存器指向栈所在的地址,有专门的机器指令完成数据入栈