动态分配内存

Java内存管理:Java内存区域 JVM运行时数据区

情到浓时终转凉″ 提交于 2019-12-01 15:28:41
Java内存管理:Java内存区域 JVM运行时数据区 在前面的一些文章了解到javac编译的大体过程、Class文件结构、以及JVM字节码指令。 下面我们详细了解Java内存区域:先说明JVM规范定义的JVM运行时分配的数据区有哪些,然后分别介绍它们的特点,并指出给出一些HotSpot虚拟机实现的不同点和调整参数。 1、Java内存区域概述 1-2、C/C++与Java程序开发的内存管理 在内存管理领域,C/C++程序开发与Java程序开发有着完全不同的理念: 1、C/C++程序开发 自己管理内存是一项基础的工作; 自已分配内存,但也得自己来及时回收; 比较自由,但多了些工作量,且容易出现内存泄露和内存溢出等问题; 2、Java程序开发 JVM管理内存,不需要自己手动分配内存和释放内存; 不容易出现内存泄露和内存溢出; 一旦出现问题不容易排查,所以得了解JVM是怎么使用内存; 1-2、Java内存区域与JVM运行时数据区 如上图, Java虚拟机规范定义了字节码执行期间使用的各种 运行时数据区 ,即JVM在执行Java程序的过程中,会把它管理的内存划分为若干个不同的数据区域,包括: 程序计数器、java虚拟机栈、本地方法栈、java堆、方法区、运行时常量池; 从线程共享角度来说,可以分为两类: 1、所有线程共享的数据区 方法区、运行时常量池、java堆;

JVM原理与深度调优

送分小仙女□ 提交于 2019-12-01 08:10:20
什么是jvm jvm是java虚拟机 运行在用户态、通过应用程序实现java代码跨平台、与平台无关、实际上是"一次编译,到处执行" 1.从微观来说编译出来的是字节码!去到哪个平台都能用,只要有那个平台的JDK就可以运行!字码好比是一个人,平台好比为国家,JDK好比这个国家的语言!只要这个人(字节码)有了这个国家的语言(JDK)就可以在这个国家(平台)生活下去。 2.JDK 是整个Java的核心,包括了Java运行环境(Java Runtime Envirnment),一堆Java工具和Java基础的类库(rt.jar)。 3.Java虚拟机(JVM)一种用于计算机设备的规范,可用不同的方式(软件或硬件)加以实现。编译虚拟机的指令集与编译微处理器的指令集非常类似。Java虚拟机包括一套字节码指令集、一组寄存器、一个栈、一个垃圾回收堆和一个存储方法域。 4.java编译出来的是一种“java字节码”,由虚拟机去解释执行。 而c和c++则编译成了二进制,直接交由操作系统执行。 5.所谓的一次编译、到处执行,即只需在一个地方编译,在其他各个平台下都可以执行。 6.与平台无关指的是JAVA只运行在自己的JVM上,不需要依赖任何其他的底层类,所以和操作系统没有任何联系,平台是说运行的系统 内存结构图 class文件 class文件径打破了 C 或者C++等语言所遵循的传统

JVM性能优化, Part 1 ―― JVM简介

浪子不回头ぞ 提交于 2019-11-29 05:27:05
众所周知,Java应用程序是运行在JVM上的,但是你对JVM有所了解么?作为这个系列文章的第一篇,本文将对经典Java虚拟机的运行机制做简单介绍,内容包括“一次编写,到处运行”的利弊、垃圾回收的基本原理、常用垃圾回收算法的示例和编译器优化等。后续的系列文章将会JVM性能优化的内容进行介绍,包括新一代JVM的设计思路,以及如何支持当今Java应用程序对高性能和高扩展性的要求。 如果你是一名程序员,那么毫无疑问,你肯定有过某种兴奋的感觉,就像是当一束灵感之光照亮了你思考方向,又像是神经元最终建立连接,又像是你解放思想开拓了新的局面。就我个人来说,我喜欢这种学习新知识的感觉。我在工作时就常常会有这种感觉,我的工作会涉及到一些JVM的相关技术,这着实令我兴奋,尤其是工作涉及到垃圾回收和JVM性能优化的时候。在这个系列中,我希望可以与你分享一些这方面的经验,希望你也会像我一样热爱JVM相关技术。 这个系列文章主要面向那些想要裂解JVM底层运行原理的Java程序员。文章立足于较高的层面展开讨论,内容涉及到垃圾回收和在不影响应用程序运行的情况下对安全快速的释放/分配内存。你将对JVM的核心模块有所了解:垃圾回收、GC算法、编译器行为,以及一些常用优化技巧。此外,还会讨论为什么对Java做基准测试(benchmark)是件很困难的事,并提供一些建议来帮助做基准测试。最后

内存管理

|▌冷眼眸甩不掉的悲伤 提交于 2019-11-28 15:44:00
内存管理 内存基本知识 什么是内存,有何作用 内存:存放数据 程序执行前需要先放到内存中才能被CPU处理--缓和CPU与硬盘之间的速度矛盾 内存地址,内存单元 进程运行的基本原理 指令的工作原理 操作码+若干参数 逻辑地址vs物理地址 程序经过编译、链接后生成的指令中指明的地址是逻辑地址(相对地址)相对于进程的起始地址而言 如何实现地址转换 装入的三种方式 绝对装入:在编译时,如果知道程序将放到内存中的那个位置,编译程序将产生绝对地址的目标代码 装入程序按照装入模块中的地址,将程序和数据装入内存 绝对装入只适用于单道程序环境 灵活性差 静态重定位:又称可重定位装入。编译、链接后的装入模块地址都是从0开始的,指令中使用的地址、数据存放的地址都是相对于起始地址而言的逻辑地址。 可根据内存的当前情况,将装入模块装入到内存的适当位置 装入时对地址进行“重定位”,将逻辑地址变换为物理地址(地址变换是在装入时一次完成的) 静态重定位的特点是在一个作业装入内存时,必须分配其要求的全部内存空间,如果没有足够的内存,就不能装入该作业 运行期间就不能再移动 动态重定位:又称动态运行时装入。编译、连接后的装入模块的地址都是从0开始的。装入程序把装入模块装入内存后,并不会立即把逻辑地址转换为物理地址,而是把地址转换推迟到程序真正要执行时才进行。 装入内存后的地址依然是逻辑地址

C++内存详解[精]

你离开我真会死。 提交于 2019-11-28 12:53:15
伟大的Bill Gates 曾经失言:   640K ought to be enough for everybody — Bill Gates 1981   程序员们经常编写内存管理程序,往往提心吊胆。如果不想触雷,唯一的解决办法就是发现所有潜伏的地雷并且排除它们,躲是躲不了的。本文的内容比一般教科书的要深入得多,读者需细心阅读,做到真正地通晓内存管理。   1、内存分配方式   内存分配方式有三种:    (1) 从静态存储区域分配 。内存在程序编译的时候就已经分配好, 这块内存在程序的整个运行期间都存在 。例如全局变量,static变量。   (2) 在栈上创建 。在执行函数时,函 数内局部变量的存储单元都可以在栈上创建,函数 执行结束时这些存储单元自动被释放 。栈内存分配运算 内置于 处理器的指令集中,效率很高 ,但是分配的内存 容量有限 。   (3) 从堆上分配 ,亦称 动态内存分配。程序在运行的时候用malloc或new申请任意多少的内存 ,程序员自己负责在何时用free或delete释放内存。动态内存的生存期由我们决定,使用非常灵活,但问题也最多。   2、常见的内存错误及其对策   发生内存错误是件非常麻烦的事情。编译器不能自动发现这些错误,通常是在程序运行时才能捕捉到。而这些错误大多没有明显的症状,时隐时现,增加了改错的难度。有时用户怒气冲冲地把你找来

【操作系统】 内存管理

假如想象 提交于 2019-11-28 01:05:27
内存管理概念 内存管理的功能有: 内存空间的分配与回收。由操作系统完成主存储器空间的分配和管理,提高编程效率。 地址转换。在多道程序环境下,程序中逻辑地址与内存中的物理地址不可能一致,因此存储管理必须提供存储变换功能,把逻辑地址转换成相应的物理地址。 内存空间的扩充。利用虚拟存储技术或自动覆盖技术,从逻辑上扩充内存。 存储保护。保证各道作业在各自的存储空间内运行,互不干扰。 创建进程首先要将程序和数据装入内存。将用户源程序变为可在内存中执行的程序,通常需要以下几个步骤: 编译。由编译程序将用户源代码编译成若干目标模块。 链接。由链接程序将编译后形成的一组目标代码及所需的库函数链接在一起,形成一个完整的装入模块。 装入。由装入程序将装入模块装入内存运行。 程序的链接有以下三种方式: 静态链接。在程序运行前,先将各自目标模块及它们所需的库函数链接成一个完整的可执行程序,以后不再拆开。 装入时动态链接。将用户源程序编译后所得到的一组目标模块,在装入内存时,采用边装入边链接的方式。 运行时动态链接。对某些目标模块的链接,是在程序执行中需要该模块时才进行的。其优点是便于修改和更新,便于实现对目标模块的共享。 内存的装入模块在装入内存时,同样有以下三种方式: 绝对装入 。在编译时,若知道某个程序将驻留在内存的某个位置,则编译程序将产生绝对地址的目标代码。绝对装入程序按照装入模块中的地址

c语言学习笔记-动态内存分配

柔情痞子 提交于 2019-11-27 21:48:55
以下内容均为看郝斌老师视频和教学大纲,总结,复制粘贴而来的笔记。 动态内存分配   传统数组的缺点     1.传统数组必须事先制定,且只能是常整数,不能是变量     2.传统形式定义的数组,该数组的内存程序员无法手动释放,在一个函数的运行期间,系统为该函数中数组所分配的空间会一直存在,直到该函数运行完毕时,数组的空间才会被系统释放     3.数组的长度一旦定义,其长度就不能在更改,数组的长度不能在函数运行过程中动态的扩充或缩小     4.传统方式定义的数组不能跨函数使用 为什么需要动态分配内存   动态数组很好的解决了传统数组的这4个缺陷   传统数组也叫静态数组 分配动态内存举例 int * p=(int *)malloc(int len) 释放动态内存的方法 free(p) 静态内存和动态内存的比较     静态内存是由系统自动分配,由系统自动释放     静态内存是在栈分配的          动态内存是由程序员手动分配,手动释放     动态内存是在堆分配的 跨函数使用内存的问题     静态内存不可以跨函数使用     静态内存在函数执行期间可以被其他函数使用     静态内存在函数执行完毕之后就不能再被其它其他函数使用了     动态内存可以跨函数使用       动态内存在函数执行完毕之后仍然可以被其他函数使用 来源: https://www.cnblogs

【转】C++ 异常

只谈情不闲聊 提交于 2019-11-27 01:24:07
一、什么是异常处理 一句话:异常处理就是处理程序中的错误。 二、为什么需要异常处理,以及异常处理的基本思想 C++之父Bjarne Stroustrup在《The C++ Programming Language》中讲到:一个库的作者可以检测出发生了运行时错误,但一般不知道怎样去处理它们(因为和用户具体的应用有关);另一方面,库的用户知道怎样处理这些错误,但却无法检查它们何时发生(如果能检测,就可以再用户的代码里处理了,不用留给库去发现)。 Bjarne Stroustrup说:提供 异常 的 基本目的 就是为了处理上面的问题。 基本思想 是:让一个函数在发现了自己无法处理的错误时抛出(throw)一个异常,然后它的(直接或者间接)调用者能够处理这个问题。 The fundamental idea is that a function that finds a problem it cannot cope with throws an exception, hoping that its (direct or indirect) caller can handle the problem. 也就是《C++ primer》中说的:将 问题检测 和 问题处理 相分离 。 Exceptions let us separate problem detection from problem

malloc函数动态分配内存

六月ゝ 毕业季﹏ 提交于 2019-11-26 02:07:32
#include <stdio.h> #include <stdlib.h> //malloc free #include <windows.h> //sleep void main1(){ //int a[1024*1024*1000]; //数组只能处理小数量的数据 int num =100; //int b[num]; 数组的大小必须明确,num是变量,随时可以变化 //数组内存这种分配机制就称为静态分配,数组使用完成后系统自动回收 //动态内存分配 /* malloc和free是C标准库中提供的两个函数,用以动态申请和释放内存,malloc()函数的基本调用格式为: void *malloc( unsigned int size ); 参数size是个无符号整型数,用户由此控制申请内存的大小,执行成功时,系统会为程序开辟一块大小为size个内存字节的区域,并将该区域的首地址返回, 用户可利用该地址管理并使用该块内存,如果申请失败(比如内存大小不够用),返回空指针NULL。 malloc()函数返回类型是void*,用其返回值对其他类型指针赋值时,必须进行显式转换。 size仅仅是申请字节的大小,并不管申请的内存块中存储的数据类型,因此,申请内存的长度须由程序员通过“长度×sizeof(类型)”的方式给出,举例来说: int* p=(int*) malloc(5*