对象存储

Java对象占用内存大小

泄露秘密 提交于 2019-11-29 08:15:09
new Object()将占用多少bytes的内存空间? 原生类型(primitive type)的内存占用 Primitive Type Memory Required(bytes) ————————————————————— boolean 1 byte 1 short 2 char 2 int 4 float 4 long 8 double 8 对象在内存中存储的布局可以分为三块区域: 对象头(Header)、实例数据(Instance Data)和对齐填充(Padding)。 HotSpot虚拟机的对象头包括两部分信息,第一部分用于存储 对象自身的运行时数据 , 如哈希码(HashCode)、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等等,这部分数据的长度在32位和64位的虚拟机(暂 不考虑开启压缩指针的场景)中分别为32个和64个Bits,官方称它为“Mark Word”。 对象需要存储的运行时数据很多,其实已经超出了32、64位Bitmap结构所能记录的限度,但是对象头信息是与对象自身定义的数据无关的额 外存储成本,考虑到虚拟机的空间效率,Mark Word被设计成一个非固定的数据结构以便在极小的空间内存储尽量多的信息,它会根据对象的状态复用自己的存储空间。例如在32位的HotSpot虚拟机 中对象未被锁定的状态下,Mark

彻底搞懂HashMap,HashTable,ConcurrentHashMap之关联

邮差的信 提交于 2019-11-29 04:17:17
Java集合类是个非常重要的知识点,HashMap、HashTable、ConcurrentHashMap等算是集合类中的重点,可谓“重中之重”,首先来看个问题,如面试官问你:HashMap和HashTable有什么区别,一个比较简单的回答是: 1、HashMap是非线程安全的,HashTable是线程安全的。 2、HashMap的键和值都允许有null值存在,而HashTable则不行。 3、因为线程安全的问题,HashMap效率比HashTable的要高。 能答出上面的三点,简单的面试,算是过了,但是如果再问:Java中的另一个线程安全的与HashMap极其类似的类是什么?同样是线程安全,它与HashTable在线程同步上有什么不同?能把第二个问题完整的答出来,说明你的基础算是不错的了。带着这个问题,本章开始深入解析HashMap和HashTable类应用而生!总想在文章的开头说点儿什么,但又无从说起。从最近的一些面试说起吧,感受就是:知识是永无止境的,永远不要觉得自己已经掌握了某些东西。如果对哪一块知识感兴趣,那么,请多多的花时间,哪怕最基础的东西也要理解它的原理,尽量往深了研究,在学习的同时,记得多与大家交流沟通,因为也许某些东西,从你自己的角度,是很难发现的,因为你并没有那么多的实验环境去发现他们。只有交流的多了,才能及时找出自己的不足,才能认识到:“哦

作用域和存储期

我的梦境 提交于 2019-11-29 04:03:24
  要创建大规模程序,必须首先理解作用域和存储期。 作用域和标识符的可见性   在如下代码所示的程序中对变量x的声明总共有三处。 /* 确认标识符的作用域 */ #include <stdio.h> int x = 75; /* A:文件作用域 */ void print_x(void) { printf("x = %d\n", x); } int main(void) { int i; int x = 999; /* B:块作用域 */ print_x();            //1 printf("x = %d\n", x);    //2 for (i = 0; i < 5; i++) { int x = i * 100; /* C:块作用域 */    //3 printf("x = %d\n", x);              //3 } printf("x = %d\n", x);          //4 return 0; }   首先我们可以看到A处声明的x。该变量的初始值为75,因为它是在函数外面声明定义的,所以这个x拥有 文件作用域 。   因此,函数print_x中的“x”就是上述的代码中出现的第一个x,程序执行后,屏幕上会输出           x = 75      显示的是第一个x的值   因为1处调用了函数print_x

java集合(list,set,map)

此生再无相见时 提交于 2019-11-29 01:54:07
java集合(list,set,map) 集合 集合与数组 数组 (可以存储基本数据类型)是用来存现对象的一种容器,但是数组的长度固定,不适合在对象数量未知的情况下使用。 集合 (只能存储对象,对象类型可以不一样)的长度可变,可在多数情况下使用。 注:数组我在前面的博客讲了大家可以看下 集合中接口和类的关系 Collection 接口是集合类的根接口,Java中没有提供这个接口的直接的实现类。但是却让其被继承产生了两个接口,就是Set和List。Set中不能包含重复的元素。List是一个有序的集合,可以包含重复的元素,提供了按索引访问的方式。 Map 是Java.util包中的另一个接口,它和Collection接口没有关系,是相互独立的,但是都属于集合类的一部分。Map包含了key-value对。Map不能包含重复的key,但是可以包含相同的value。 Iterator 所有的集合类,都实现了Iterator接口,这是一个用于遍历集合中元素的接口,主要包含以下三种方法: 1. hasNext() 是否还有下一个元素。 2. next() 返回下一个元素。 3. remove() 删除当前元素。 层次图 图一这个比较简单 图二完整 list,set,map对比 接口 子接口 是否有序 是否允许元素重复 Collection            否   List   

Java 内存区域和GC机制

社会主义新天地 提交于 2019-11-28 23:24:12
目录 Java垃圾回收概况 Java内存区域 Java对象的访问方式 Java内存分配机制 Java GC机制 垃圾收集器 Java垃圾回收概况   Java GC(Garbage Collection,垃圾收集,垃圾回收)机制,是Java与C++/C的主要区别之一,作为Java开发者,一般不需要专门编写内存回收和垃圾清理代 码,对内存泄露和溢出的问题,也不需要像C程序员那样战战兢兢。这是因为在Java虚拟机中,存在自动内存管理和垃圾清扫机制。概括地说,该机制对 JVM(Java Virtual Machine)中的内存进行标记,并确定哪些内存需要回收,根据一定的回收策略,自动的回收内存,永不停息(Nerver Stop)的保证JVM中的内存空间,放置出现内存泄露和溢出问题。   关于JVM,需要说明一下的是,目前使用最多的Sun公司的JDK中,自从 1999年的JDK1.2开始直至现在仍在广泛使用的JDK6,其中默认的虚拟机都是HotSpot。2009年,Oracle收购Sun,加上之前收购 的EBA公司,Oracle拥有3大虚拟机中的两个:JRockit和HotSpot,Oracle也表明了想要整合两大虚拟机的意图,但是目前在新发布 的JDK7中,默认的虚拟机仍然是HotSpot,因此本文中默认介绍的虚拟机都是HotSpot,相关机制也主要是指HotSpot的GC机制。  

操作系统

孤街醉人 提交于 2019-11-28 21:35:18
C的内存分配 32bitCPU可寻址4G线性空间, 每个进程都有各自独立的4G逻辑地址, 其中0~3G是用户态空间, 3~4G是内核空间, 不同进程相同的逻辑地址会映射到不同的物理地址中. 其逻辑地址其划分如下: 正文段(code segment/text segment, .text段): 或称代码段, 通常是用来存放程序执行代码的一块内存区域. 这部分区域的大小在程序运行前就已经确定, 并且内存区域通常属于只读, 某些架构也允许代码段为可写, 即允许修改程序. 在代码段中, 也有可能包含一些只读的常数变量, 例如字符串常量等 . CPU执行的机器指令部分. ( 存放函数体的二进制代码 . ) 只读数据段(RO data, .rodata):只读数据段是程序使用的一些不会被改变的数据, 使用这些数据的方式类似查表式的操作, 由于这些变量不需要修改, 因此只需放在只读存储器中. 已初始化读写数据段(data segment, .data段):通常是用来存放程序中已初始化的全局变量的一块内存区域. 数据段属于静态内存分配. 常量字符串就是放在这里的, 程序结束后由系统释放(rodata—read only data). 已初始化读写数据段(RW data, .data):已初始化数据是在程序中声明, 并且具有初值的变量, 这些变量需要占用存储器空间,

Java并发编程知识点总结Volatile、Synchronized、Lock实现原理

允我心安 提交于 2019-11-28 20:40:53
Volatile 关键字及其实现原理   在多线程并发编程中, Volatile 可以理解为轻量级的 Synchronized ,用 volatile 关键字声明的变量,叫做共享变量,其保证了变量的“可见性”以及“有序性”。可见性的意思是当一个线程修改一个共享变量时,另外一个线程能读到这个修改的值。可见性是由 Java 内存模型保证的(底层还是通过内存屏障实现的),即某个线程改变共享变量的值之后,会立即同步到主内存,线程每次使用共享变量的时候都先从内存中读取刷新它的值;而有序性是通过“内存屏障”实现的,通过禁止指令重排序,从而使得某些代码能以一定的顺序执行。   但是 Volatile 关键字不能保证对共享变量操作的“原子性”,比如自增操作( i++ )就不是原子操作,其可以分解为:①从内存中读取 i 的值,②对 i 进行自增操作,③将 i 的值写入到内存中;因此 volatile 关键字也不能完全保证多线程下的安全性。   在了解 volatile 关键字的原理之前,首先来看一下与其实现原理相关的 CPU 术语与说明。 图 1. 与 volatile 实现原理相关的相关 CPU 术语与说明   通过对声明了 volatile 变量的 Java 语句进行反编译可以发现,有 volatile 变量修饰的共享变量进行写操作的时候会多出第二行汇编代码, 其中 Lock

OpenStack构架知识梳理

橙三吉。 提交于 2019-11-28 19:46:18
OpenStack既是一个社区,也是一个项目和一个开源软件,提供开放源码软件,建立公共和私有云,它提供了一个部署云的操作平台或工具集,其宗旨在于:帮助组织运行为虚拟计算或存储服务的云,为公有云、私有云,也为大云、小云提供可扩展的、灵活的云计算。 OpenStackd开源项目由社区维护,包括OpenStack计算(代号为Nova),OpenStack对象存储(代号为Swift),并OpenStack镜像服务(代号Glance)的集合。 OpenStack提供了一个操作平台,或工具包,用于编排云。 下面列出 Openstack的详细构架图 Openstack的网络拓扑结构图 整个OpenStack是由控制节点,计算节点,网络节点,存储节点四大部分组成。(这四个节点也可以安装在一台机器上,单机部署) 其中: 控制节点 负责对其余节点的控制,包含虚拟机建立,迁移,网络分配,存储分配等等 计算节点 负责虚拟机运行 网络节点 负责对外网络与内网络之间的通信 存储节点 负责对虚拟机的额外存储管理等等 控制节点架构: 控制节点包括以下服务 管理支持服务 基础管理服务 扩展管理服务 1)管理支持服务包含MySQL与Qpid两个服务 MySQL:数据库作为基础/扩展服务产生的数据存放的地方 Qpid:消息代理(也称消息中间件)为其他各种服务之间提供了统一的消息通信服务 2

一文搞懂Python中的所有数组数据类型

冷暖自知 提交于 2019-11-28 19:30:50
关于我 一个有思想的程序猿,终身学习实践者,目前在一个创业团队任team lead,技术栈涉及Android、Python、Java和Go,这个也是我们团队的主要技术栈。 Github: https://github.com/hylinux1024 微信公众号:终身开发者(angrycode) 数组类型是各种编程语言中基本的数组结构了,本文来盘点下 Python 中各种“数组”类型的实现。 list tuple array.array str bytes bytearray 其实把以上类型都说成是数组是不准确的。这里把数组当作一个广义的概念,即把列表、序列、数组都当作 array-like 数据类型来理解。 **注意本文所有代码都是在 Python3.7 中跑的^_^** 0x00 可变的动态列表list list 应该是 Python 最常用到的数组类型了。它的特点是 可变的、能动态扩容,可存储 Python 中的一切对象,使用时不用指定存储的元素的类型 。 使用非常简单 >>> arr = ["one","two","three"] >>> arr[0] 'one' # 动态扩容 >>> arr.append(4) >>> arr ['one', 'two', 'three', 4] # 删除一个元素 >>> del arr[2] >>> arr ['one', 'two',

学习第十三天(2019-11-26)

瘦欲@ 提交于 2019-11-28 19:05:53
第二十二章 高级技巧 一、高级函数 1、安全的类型检测 由于typeof会出现无法预知的行为,instanceof在多个全局作用域中并不能正确工作,所以调用Object原生的toString方法,会返回[Object NativeConstructorName]格式字符串。每个类内部都有一个[[Class]]属性,这个属性中就指定了上述字符串中的构造函数名。 原生数组的构造函数名与全局作用域无关,因此使用toString方法能保证返回一致的值,为此可以创建如下函数: 1 function isArray(value){ 2 return Object.prototype.toString.call(value) == "[object Array]"; 3 } 也可以基于这一思路测试某个值是不是原生函数或正则表达式:(这一技巧广泛用来检测原生JSON对象) 1 //判断是否原生函数 2 function isFunction(value){ 3 return Object.prototype.toString.call(value) == "[object Function]"; 4 } 5 //判断是否原生函数 6 function isFunction(value){ 7 return Object.prototype.toString.call(value) == "