精华内容
下载资源
问答
  • Struts1Struts2的区别和对比,从各个方面对 Struts1Struts2进行了详细的介绍及比较
  • 1、MyISAM:默认表类型,它是...不是事务安全,而且不支持外键,如果执行大量select,insert MyISAM比较适合。 2、InnoDB:支持事务安全引擎,支持外键、行锁、事务是他最大特点。如果有大量updatei...

    1、MyISAM:默认表类型,它是基于传统的ISAM类型,ISAM是Indexed Sequential Access Method (有索引的顺序访问方法) 的缩写,它是存储记录和文件的标准方法。不是事务安全的,而且不支持外键,如果执行大量的select,insert MyISAM比较适合。

    2、InnoDB:支持事务安全的引擎,支持外键、行锁、事务是他的最大特点。如果有大量的update和insert,建议使用InnoDB,特别是针对多个并发和QPS较高的情况。

     

    一、表锁差异

    MyISAM:

    myisam只支持表级锁,用户在操作myisam表时,select,update,delete,insert语句都会给表自动加锁,如果加锁以后的表满足insert并发的情况下,可以在表的尾部插入新的数据。也可以通过lock table命令来锁表,这样操作主要是可以模仿事务,但是消耗非常大,一般只在实验演示中使用。

    InnoDB :

    Innodb支持事务和行级锁,是innodb的最大特色。

    事务的ACID属性:atomicity,consistent,isolation,durable。

    并发事务带来的几个问题:更新丢失,脏读,不可重复读,幻读。

    事务隔离级别:未提交读(Read uncommitted),已提交读(Read committed),可重复读(Repeatable read),可序列化(Serializable)

     

     

    查看mysql的默认事务隔离级别“show global variables like ‘tx_isolation’; ”

    Innodb的行锁模式有以下几种:共享锁,排他锁,意向共享锁(表锁),意向排他锁(表锁),间隙锁。

    注意:当语句没有使用索引,innodb不能确定操作的行,这个时候就使用的意向锁,也就是表锁

    关于死锁:

    什么是死锁?当两个事务都需要获得对方持有的排他锁才能完成事务,这样就导致了循环锁等待,也就是常见的死锁类型。

    解决死锁的方法:

    1、  数据库参数

    2、  应用中尽量约定程序读取表的顺序一样

    3、  应用中处理一个表时,尽量对处理的顺序排序

    4、  调整事务隔离级别(避免两个事务同时操作一行不存在的数据,容易发生死锁)

     

    二、数据库文件差异
    MyISAM :

    myisam属于堆表

    myisam在磁盘存储上有三个文件,每个文件名以表名开头,扩展名指出文件类型。

    .frm 用于存储表的定义

    .MYD 用于存放数据

    .MYI 用于存放表索引

    myisam表还支持三种不同的存储格式:

    静态表(默认,但是注意数据末尾不能有空格,会被去掉)

    动态表

    压缩表

    InnoDB :

    innodb属于索引组织表

    innodb有两种存储方式,共享表空间存储和多表空间存储

    两种存储方式的表结构和myisam一样,以表名开头,扩展名是.frm。

    如果使用共享表空间,那么所有表的数据文件和索引文件都保存在一个表空间里,一个表空间可以有多个文件,通过innodb_data_file_path和innodb_data_home_dir参数设置共享表空间的位置和名字,一般共享表空间的名字叫ibdata1-n。

    如果使用多表空间,那么每个表都有一个表空间文件用于存储每个表的数据和索引,文件名以表名开头,以.ibd为扩展名。

     

    三、索引差异

    1、关于自动增长

    myisam引擎的自动增长列必须是索引,如果是组合索引,自动增长可以不是第一列,他可以根据前面几列进行排序后递增。

    innodb引擎的自动增长咧必须是索引,如果是组合索引也必须是组合索引的第一列。

    2、关于主键

    myisam允许没有任何索引和主键的表存在,

    myisam的索引都是保存行的地址。

    innodb引擎如果没有设定主键或者非空唯一索引,就会自动生成一个6字节的主键(用户不可见)

    innodb的数据是主索引的一部分,附加索引保存的是主索引的值。

    3、关于count()函数

    myisam保存有表的总行数,如果select count(*) from table;会直接取出出该值

    innodb没有保存表的总行数,如果使用select count(*) from table;就会遍历整个表,消耗相当大,但是在加了wehre       条件后,myisam和innodb处理的方式都一样。

    4、全文索引

    myisam支持 FULLTEXT类型的全文索引

    innodb不支持FULLTEXT类型的全文索引,但是innodb可以使用sphinx插件支持全文索引,并且效果更好。(sphinx   是一个开源软件,提供多种语言的API接口,可以优化mysql的各种查询)

    5、delete from table

    使用这条命令时,innodb不会从新建立表,而是一条一条的删除数据,在innodb上如果要清空保存有大量数据的表,最       好不要使用这个命令。(推荐使用truncate table,不过需要用户有drop此表的权限)

    6、索引保存位置

    myisam的索引以表名+.MYI文件分别保存。

    innodb的索引和数据一起保存在表空间里。

     

    四、开发的注意事项

    1、可以用 show create table tablename 命令看表的引擎类型。

    2、对不支持事务的表做start/commit操作没有任何效果,在执行commit前已经提交。

    3、可以执行以下命令来切换非事务表到事务(数据不会丢失),innodb表比myisam表更安全:alter table tablename type=innodb;或者使用 alter table tablename engine = innodb;

    4、默认innodb是开启自动提交的,如果你按照myisam的使用方法来编写代码页不会存在错误,只是性能会很低。如何在编写代码时候提高数据库性能呢?

    a、尽量将多个语句绑到一个事务中,进行提交,避免多次提交导致的数据库开销。

    b、在一个事务获得排他锁或者意向排他锁以后,如果后面还有需要处理的sql语句,在这两条或者多条sql语句之间程序应尽量少的进行逻辑运算和处理,减少锁的时间。

    c、尽量避免死锁

    d、sql语句如果有where子句一定要使用索引,尽量避免获取意向排他锁。

    f、针对我们自己的数据库环境,日志系统是直插入,不修改的,所以我们使用混合引擎方式,ZION_LOG_DB照旧使用myisam存储引擎,只有ZION_GAME_DB,ZION_LOGIN_DB,DAUM_BILLING使用Innodb引擎。

     

    五、究竟该怎么选择

    下面先让我们回答一些问题:  

    ◆你的数据库有外键吗?  

    ◆你需要事务支持吗?  

    ◆你需要全文索引吗?  

    ◆你经常使用什么样的查询模式?  

    ◆你的数据有多大?  
     
    myisam只有索引缓存  
    innodb不分索引文件数据文件 innodb buffer  
    myisam只能管理索引,在索引数据大于分配的资源时,会由操作系统来cache;数据文件依赖于操作系统的cache。innodb不管是索引还是数据,都是自己来管理  
     
    思考上面这些问题可以让你找到合适的方向,但那并不是绝对的。如果你需要事务处理或是外键,那么InnoDB 可能是比较好的方式。如果你需要全文索引,那么通常来说 MyISAM是好的选择,因为这是系统内建的,然而,我们其实并不会经常地去测试两百万行记录。所以,就算是慢一点,我们可以通过使用Sphinx从InnoDB中获得全文索引。  
     
    数据的大小,是一个影响你选择什么样存储引擎的重要因素,大尺寸的数据集趋向于选择InnoDB方式,因为其支持事务处理和故障恢复。数据库的在小决定了故障恢复的时间长短,InnoDB可以利用事务日志进行数据恢复,这会比较快。而MyISAM可能会需要几个小时甚至几天来干这些事,InnoDB只需要几分钟。  
     
    操作数据库表的习惯可能也会是一个对性能影响很大的因素。比如: COUNT() 在 MyISAM 表中会非常快,而在InnoDB 表下可能会很痛苦。而主键查询则在InnoDB下会相当相当的快,但需要小心的是如果我们的主键太长了也会导致性能问题。大批的inserts 语句在 MyISAM下会快一些,但是updates 在InnoDB下会更快一些——尤其在并发量大的时候。  
     
    所以,到底你检使用哪一个呢?根据经验来看,如果是一些小型的应用或项目,那么MyISAM 也许会更适合。当然,在大型的环境下使用 MyISAM 也会有很大成功的时候,但却不总是这样的。如果你正在计划使用一个超大数据量的项目,而且需要事务处理或外键支持,那么你真的应该直接使用 InnoDB方式。但需要记住InnoDB 的表需要更多的内存和存储,转换100GB 的MyISAM 表到InnoDB 表可能会让你有非常坏的体验。  
     
    对于支持事务的InnoDB类型的表,影响速度的主要原因是AUTOCOMMIT默认设置是打开的,而且程序没有显式调用BEGIN 开始事务,导致每插入一条都自动Commit,严重影响了速度。可以在执行sql前调用begin,多条sql形成一个事务(即使autocommit打开也可以),将大大提高性能。  

     

    InnoDB

    InnoDB 给 MySQL 提供了具有事务(commit)、回滚(rollback)和崩溃修复能力 (crash recovery capabilities)的事务安全(transaction-safe (ACID compliant))型表。 InnoDB 提供了行锁(locking on row level),提供与 Oracle 类型一致的不加锁读取(non- locking read in SELECTs)。这些特性均提高了多用户并发操作的性能表现。在InnoDB表中不需要扩大锁定 (lock escalation),因为 InnoDB 的列锁定(row level locks)适宜非常小的空间。 InnoDB 是 MySQL 上第一个提供外键约束(FOREIGN KEY constraints)的表引擎。  

    InnoDB 的设计目标是处理大容量数据库系统,它的 CPU 利用率是其它基于磁盘的关系数据库引擎所不能比的。在技术上,InnoDB 是一套放在 MySQL 后台的完整数据库系统,InnoDB 在主内存中建立其专用的缓冲池用于高速缓冲数据和索引。 InnoDB 把数据和索引存放在表空间里,可能包含多个文件,这与其它的不一样,举例来说,在 MyISAM 中,表被存放在单独的文件中。InnoDB 表的大小只受限于操作系统的文件大小,一般为 2 GB。  
    InnoDB所有的表都保存在同一个数据文件 ibdata1 中(也可能是多个文件,或者是独立的表空间文件),相对来说比较不好备份,免费的方案可以是拷贝数据文件、备份 binlog,或者用 mysqldump。  


    MyISAM  
    MyISAM 是MySQL缺省存贮引擎 .  
    每张MyISAM 表被存放在三个文件 。frm 文件存放表格定义。 数据文件是MYD (MYData) 。 索引文件是 MYI (MYIndex) 引伸。  
    因为MyISAM相对简单所以在效率上要优于InnoDB..小型应用使用MyISAM是不错的选择.  
    MyISAM表是保存成文件的形式,在跨平台的数据转移中使用MyISAM存储会省去不少的麻烦  
     
    以下是一些细节和具体实现的差别:  
     
    1.InnoDB不支持FULLTEXT类型的索引。  
    2.InnoDB 中不保存表的具体行数,也就是说,执行select count(*) from table时,InnoDB要扫描一遍整个表来计算有多少行,但是MyISAM只要简单的读出保存好的行数即可。注意的是,当count(*)语句包含 where条件时,两种表的操作是一样的。  
    3.对于AUTO_INCREMENT类型的字段,InnoDB中必须包含只有该字段的索引,但是在MyISAM表中,可以和其他字段一起建立联合索引。  
    4.DELETE FROM table时,InnoDB不会重新建立表,而是一行一行的删除。  
    5.LOAD TABLE FROM MASTER操作对InnoDB是不起作用的,解决方法是首先把InnoDB表改成MyISAM表,导入数据后再改成InnoDB表,但是对于使用的额外的InnoDB特性(例如外键)的表不适用。  

    另外,InnoDB表的行锁也不是绝对的,如果在执行一个SQL语句时MySQL不能确定要扫描的范围,InnoDB表同样会锁全表,例如 update table set num=1 where name like “%aaa%”  

    任何一种表都不是万能的,只用恰当的针对业务类型来选择合适的表类型,才能最大的发挥MySQL的性能优势。  

     

    六、重复地总结一遍

    1、MyISAM不支持事务,InnoDB是事务类型的存储引擎,当我们的表需要用到事务支持的时候,那肯定是不能选择MyISAM了。

    2、MyISAM只支持表级锁,BDB支持页级锁和表级锁默认为页级锁,而InnoDB支持行级锁和表级锁默认为行级锁
     
    表级锁:直接锁定整张表,在锁定期间,其他进程无法对该表进行写操作,如果设置的是写锁,那么其他进程读也不允许
     
    MyISAM是表级锁定的存储引擎,它不会出现死锁问题
     
    对于write,表锁定原理如下:
     
    如果表上没有锁,在其上面放置一个写锁,否则,把锁定请求放在写锁队列中。
     
    对于read,表锁定原理如下 :
     
    如果表上没有写锁定,那么把一个读锁放在其上面,否则把锁请求放在读锁定队列中
     
    当一个锁定被释放时,表可被写锁定队列中的线程得到,然后才是读锁定队列中的线程。这意味着,如果你在一个表上有许多更新,那么你的SELECT语句将等到所有的写锁定线程执行完。

    行级锁:只对指定的行进行锁定,其他进程还是可以对表中的其他行进行操作的。
     
    行级锁是Mysql粒度最小的一种锁,它能大大的减少数据库操作的冲突,但是粒度越小实现成本也越大。
     
    行级锁可能会导致“死锁”,那到底是怎么导致的呢,分析原因:Mysql行级锁并不是直接锁记录,而是锁索引。索引分为主键索引和非主键索引两种,如果一条sql语句操作了主键索引,那么Mysql就会锁定这个主键索引,如果sql语句操作的是非主键索引,那么Mysql会先锁定这个非主键索引,再去锁定主键索引。
     
    在UPDATE 和 DELETE操作时Mysql不仅会锁定所有WHERE 条件扫描过得索引,还会锁定相邻的键值。
     
    “死锁”举例分析:
     
    表Test:(ID,STATE,TIME)  主键索引:ID  非主键索引:STATE
     
    当执行"UPDATE  STATE =1011 WHERE STATE=1000"  语句的时候会锁定STATE索引,由于STATE 是非主键索引,所以Mysql还会去请求锁定ID索引
     
    当另一个SQL语句与语句1几乎同时执行时:“UPDATE STATE=1010 WHERE ID=1”  对于语句2 Mysql会先锁定ID索引,由于语句2操作了STATE字段,所以Mysql还会请求锁定STATE索引。这时。彼此锁定着对方需要的索引,又都在等待对方释放锁定。所以出现了"死锁"的情况。
     
    行级锁的优点:
     
    有许多线程访问不同的行时,只存在少量的冲突。
     
    回滚时只有少量的更改
     
    可以长时间锁定单一的行
     
    行级锁缺点:
     
    相对于页级锁和表级锁来说占用了更多的内存
     
    当表的大部分行在使用时,比页级锁和表级锁慢,因为你必须获得更多的锁
     
    当在大部分数据上经常使用GROUP BY操作,肯定会比表级锁和页级锁慢。
     
    页级锁:表级锁速度快,但是冲突多;行级锁速度慢,但冲突少;页级锁就是他俩折中的,一次锁定相邻的一组记录。

    3、MyISAM引擎不支持外键,InnoDB支持外键

    4、MyISAM引擎的表在大量高并发的读写下会经常出现表损坏的情况
     
    我们以前做的项目就遇到这个问题,表的INSERT 和 UPDATE操作很频繁,原来用的MyISAM引擎,导致表隔三差五就损坏,后来更换成了InnoDB引擎。
     
    其他容易导致表损坏原因:
     
    服务器突然断电导致数据文件损坏,强制关机(mysqld未关闭情况下)导致表损坏
     
    mysqld进程在写入操作的时候被杀掉
     
    磁盘故障
     
    表损坏常见症状:
     
    查询表不能返回数据或返回部分数据
     
    打开表失败: Can’t open file: ‘×××.MYI’ (errno: 145) 。
     
    Error: Table 'p' is marked as crashed and should be repaired 。

    Incorrect key file for table: '...'. Try to repair it
     
    Mysql表的恢复:

    对于MyISAM表的恢复:

    可以使用Mysql自带的myisamchk工具: myisamchk -r tablename  或者 myisamchk -o tablename(比前面的更保险) 对表进行修复

    5、对于count()查询来说MyISAM更有优势

    因为MyISAM存储了表中的行数记录,执行SELECT COUNT() 的时候可以直接获取到结果,而InnoDB需要扫描全部数据后得到结果。

    但是注意一点:对于带有WHERE 条件的 SELECT COUNT()语句两种引擎的表执行过程是一样的,都需要扫描全部数据后得到结果

    6、 InnoDB是为处理巨大数据量时的最大性能设计,它的CPU效率可能是任何其它基于磁盘的关系数据库引擎所不能匹敌的。

    7、MyISAM支持全文索引(FULLTEXT),InnoDB不支持

    8、MyISAM引擎的表的查询、更新、插入的效率要比InnoDB高

    网上截取了前辈们测试结论:

    测试方法:连续提交10个query, 表记录总数:38万 , 时间单位 s
     
            引擎类型                    MyISAM                InnoDB              性能相差
     
            count                      0.0008357            3.0163                3609
     
            查询主键                  0.005708              0.1574                27.57
     
            查询非主键                  24.01                  80.37                3.348
     
            更新主键                  0.008124            0.8183                100.7
     
            更新非主键                0.004141            0.02625              6.338
     
            插入                        0.004188            0.3694                88.21
     

        (1)加了索引以后,对于MyISAM查询可以加快:4 206.09733倍,对InnoDB查询加快510.72921倍,同时对MyISAM更新速度减慢为原来的1/2,InnoDB的更
      新速度减慢为原来的1/30。要看情况决定是否要加索引,比如不查询的log表,不要做任何的索引。
     
        (2)如果你的数据量是百万级别的,并且没有任何的事务处理,那么用MyISAM是性能最好的选择。
     
        (3)InnoDB表的大小更加的大,用MyISAM可省很多的硬盘空间。
     
            在我们测试的这个38w的表中,表占用空间的情况如下:
                引擎类型                    MyISAM              InnoDB
                数据                      53,924 KB          58,976 KB
                索引                      13,640 KB          21,072 KB
                占用总空间              67,564 KB          80,048 KB
     
            另外一个176W万记录的表, 表占用空间的情况如下:
     
                引擎类型                MyIsam              InnorDB
                数据                  56,166 KB          90,736 KB
                索引                  67,103 KB          88,848 KB
                占用总空间        123,269 KB        179,584 KB

     

    七、性能对比


    测试的版本是mysql  Ver 14.14 Distrib 5.1.49, for debian-linux-gnu (i686),使用的是Innodb plugin 1.0.8(官方称比built-in版本性能更好)和默认的MyISAM。

    测试机器是笔记本,配置如下:Intel 酷睿2双核 P8600,2G*2 DDR3 1066内存,320G硬盘5400转。

    测试一:数据插入性能测试,这里我分别对innodb_flush_log_at_trx_commit参数打开和关闭都测了了一下,每次测试都是运行40s,表中数字都是实际插入条数。

                           MyISAM                 Innodb (打开)      Innodb (关闭)

    单线程,逐个插入         120000                 60000              60000

    4线程,逐个插入          40000*4                20000*4            40000*4

    单线程,批量100条/次插入  3600*100               800*100            3000*100

    单线程,批量200条/次插入  1800*200               400*200            1600*200

    可以发现批量插入的性能远高于单条插入,但是一次批量的大小对性能影响不大。每条记录是否都刷新日志的参数对innodb性能的影响巨大。总体上来说,MyISAM性能更优一点。这里有一点需要注意,在插入测试过程中,我对系统资源进行了监控,发现MyISAM对系统资源占用很低,但是Innodb对磁盘占用却很高,应该是对事务控制多了很多需要记录的日志。

    测试二:数据读取性能测试。每次随机读取1000条记录,反复进行读取。

                            MyISAM        Innodb

    单线程,200次读取         5.7s          16.7s

    4线程,200次读取          12s           40.8s

    可以看出MyISAM的读取性能非常恐怖,性能差距在3倍的样子。

    以上两个测试发现MyISAM在无事务的需求下几乎完胜,但是要知道它是表锁,Innodb是行锁,那么在并发读写同时存在的情况下,那结果会是怎么样呢?!

    测试三:两个线程并发写入,2个线程并发读取。

                           MyISAM                                 Innodb

    逐个插入                写入40s:10000*2 读取200次*2:14s        写入40s:60000*2 读取200次*2:50s

    批量100条/次插入        写入40s:1000*100*2 读取200次*2:10s      写入40s:1500*100*2 读取200次*2:50s

    这下立刻显示出Innodb在并发情况下强劲的性能,几乎没有什么性能衰减。而MyISAM单条插入速度变得非常慢,批量插入也下降了40%性能。

    总结一下,在写多读少的应用中还是Innodb插入性能更稳定,在并发情况下也能基本,如果是对读取速度要求比较快的应用还是选MyISAM。


    原文:https://blog.csdn.net/wjtlht928/article/details/46641865

    转载于:https://www.cnblogs.com/dannylinux/p/9829868.html

    展开全文
  • 的区别我们要数据结构方向虚拟机内存方向从两方面去比较,两处所说的堆栈是不同的两种含义。 数据结构方向 堆栈都是一种数据项按序排列的数据结构 。 栈是线性结构LIFO,只允许在栈顶进行删除(出栈)或...

    堆heap和栈stack的区别

    堆和栈的区别我们要数据结构方向和虚拟机内存方向从两方面去比较,两处所说的堆栈是不同的两种含义。

    数据结构方向

    堆和栈都是一种数据项按序排列的数据结构 ,都用于存放临时数据

    1. 栈是线性结构LIFO,只允许在栈顶进行删除(出栈)或插入(入栈)操作。
    2. 堆一般指二叉堆,可看着一棵树。堆的根节点是最大值或者最小值,增加删除是任意的。常用于堆排序。内存中保存new 和malloc这些自定义的内存变量。
    3. 队列先进先出,在队头做删除操作,在队尾做插入操作。

    虚拟机内存方向

    一般情况下程序存放在Rom或Flash中,运行时需要拷到内存中执行,内存会分别存储不同的信息。其内存中数据分配地址如下:

    1. 栈区(stack): 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。

    2. 堆区(heap):一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表,呵呵。

    3. 全局区(static静态区):全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。
      静态区是一个可读可写的内存空间,这个空间是在你写程序编译好的空间地址(由编译器决定),是固定的。- 程序结束后有系统释放

    4. 文字常量区:常量字符串就是放在这里的。 程序结束后由系统释放

    5. 程序代码区:存放函数体的二进制代码。

    创建和销毁

    1) 栈:由操作系统自动分配释放 ,其在操作系统建立某个进程或线程时建立存储空间,在编译时可以指定需要的Stack的大小。
    栈一般处于较高地址位,栈地址是向下增长的。在退出函数的时候,只是修改栈指针就可以把栈中的内容销毁,所以速度最快。

    栈中存放函数的参数值,局部变量的值等,都是在栈中分配空间保存,从上往下分配地址。其操作方式类似于数据结构中的栈,如int a=10,自动分配自动回收。程序通过栈的基地址和偏移量来访问本地变量。

    2)堆:是应用程序在运行的时候请求操作系统分配给自己内存,由程序员申请和释放,所以它是动态申请的。对堆的访问和对一般内存的访问没有区别。

    堆区的起始地址一般处于低位,地址向上增长。若程序员不释放,程序结束时可能由OS回收。分配方式类似于链表。如我们定义int[] arr=new int[10]。

    Java和C/C++关于堆是有区别的

    1. 在Java中除了简单类型(int,char等)都是在堆中分配内存,这也是程序慢的一个主要原因
    2. C/C++ 中不是自动初始化的,C/C++分别用malloc/New请求分配Heap,用free/delete销毁内存。
    3. Java中分配Heap内存是自动初始化的。在Java中所有的对象(包括int的wrapper Integer)都是在堆中分配的。
    4. 也就说比如一个String建立对象时从两个地方都分配内存,在Heap中分配的内存实际建立这个对象,而在Stack中分配的内存只是一个指向这个堆对象的指针(引用)而已。

    缓存方式

    1. 栈使用的是一级缓存, 栈上的数据生存周期只在函数运行过程中,调用完毕立即释放,其后不能再被访问。
    2. 堆是存放在二级缓存中,生命周期由虚拟机的垃圾回收算法来决定(并不是一旦成为孤儿对象就能被回收)。所以调用这些对象的速度要相对来得低一些。

    申请响应

    栈:只要栈的剩余空间大于所申请空间,系统将为程序提供内存,否则将报异常提示栈溢出。
    堆:首先应该知道操作系统有一个记录空闲内存地址的链表,当系统收到程序的申请时,会遍历该链表,寻找第一个空间大于所申请空间的堆。
    在C++中堆事先是没有在进程空间里分配的需要手动分配,此时访问堆空间会报一个内存访问错误,而Java会自动初始化。

    堆内存分配过程
    1)记录链表将合适的堆结点从空闲结点链表中删除,并将该结点的空间分配给程序。
    2)对于大多数系统,会在这块内存空间中的首地址处记录本次分配的大小,这样,代码中的 delete语句才能正确的释放本内存空间。
    3) 由于找到的堆结点的大小不一定正好等于申请的大小,系统会自动的将多余的那部分重新放入空闲链表中。
    堆会在申请后还要做一些后续的工作,这就会引出申请效率的问题。

    栈内存分配过程
    在C++中当进程初始化时,系统会自动为进程创建一个默认栈。这个栈默认所占内存的大小根据不同系统有所不同。
    进程的每个线程都有私有的“栈”,所以每个线程虽然代码一样,但本地变量的数据都是互不干扰。一个栈可以通过“基地址”和“栈顶”地址来描述。

    栈访问

    1)有一组CPU指令可以实现对进程的内存实现堆栈访问。其中,POP指令实现出栈操作,PUSH指令实现入栈操作。
    2)CPU的ESP寄存器存放当前线程的栈顶指针,EBP寄存器中保存当前线程的栈底指针。
    3)CPU的EIP寄存器存放下一个CPU指令存放的内存地址,当CPU执行完当前的指令后,从EIP寄存器中读取下一条指令的内存地址,然后继续执行。

    申请效率

    栈:由系统自动分配,速度较快。但程序员是无法控制的。

    堆:是由new分配的内存,一般速度比较慢,而且容易产生内存碎片,不过用起来最方便。
    由于从操作系统管理的内存分配所以在分配和销毁时都要占用时间,所以用堆的效率低的多!但是堆的好处是可以做的很大,C/C++对分配的Heap是不初始化的。

    申请大小的限制

    栈:在Windows下,栈是向低地址扩展的数据结构,是一块连续的内存的区域。栈顶的地址和栈的最大容量是系统预先规定好的,windows下的栈一般只有1-2M。如果申请的空间超过栈的剩余空间时,将提示栈溢出。

    堆:堆是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。由此可见,堆获得的空间比较灵活,也比较大。

    **由于栈的大小有限,所以用子函数还是有物理意义的,而不仅仅是逻辑意义。**多使用子函数和控制函数的行数,可以有效减小栈大小限制压力。

    存储内容

    栈: 在函数调用时,第一个进栈的是主函数中函数调用后的下一条指令(函数调用语句的下一条可执行语句)的地址,然后是函数的各个参数。
    在大多数的C编译器中,参数是由右往左入栈的,然后是函数中的局部变量。注意静态变量是不入栈的。

    当本次函数调用结束后,局部变量先出栈,然后是参数,最后栈顶指针指向最开始存的地址,也就是主函数中的下一条指令,程序由该点继续运行。

    堆:一般是在堆的头部用一个字节存放堆的大小。堆中的具体内容由程序员安排。

    总结

    有人将栈比喻成去饭馆吃饭,只管点才吃饭,快捷而自由度小。堆则像自己做饭菜,过程麻烦,但想吃啥做啥,自由度高。

    博客书写不易,您的点赞收藏是我前进的动力,千万别忘记点赞、 收**藏 ^ _ ^ !

    相关链接

    展开全文
  • C/C++ 中gccg++的对比区别 一、区别 1. gcc是GCC中c编译器 g++是GCC中c++编译器 2. 对于后缀为.c文件,gcc当成c文件处理,而g++当成c++处理 对于后缀为.cpp文件,两者都当成.cpp文件处理 3. ...
  • *差异比较是关联查询时,hibernate为了保证POJO数据完整性,需要将关联数据加载,需要额外地查询更多数据。这里hibernate并没有提供相应灵活性。   关联时一个差异比较地方则是懒加载特性。其中...

    *myBatis在所有情况下,特别是插入与单表查询,都会微微优于hibernate。不过差异情况并不明显,可以基本忽略差异。

    *差异比较大的是关联查询时,hibernate为了保证POJO的数据完整性,需要将关联的数据加载,需要额外地查询更多的数据。这里hibernate并没有提供相应的灵活性。

     

    关联时一个差异比较大的地方则是懒加载特性。其中hibernate可以特别地利用POJO完整性来进行缓存,可以在一级与二级缓存上保存对象,如果对单一个对象查询比较多的话,会有很明显的性能效益。
    以后关于单对象关联时,可以通过懒加载加二级缓存的方式来提升性能。
    最后,数据查询的性能与orm框架关无太大的关系,因为orm主要帮助开发人员将关系数据转化成对象型数据模型,对代码的深析上来看,hibernate设计得比较重量级,对开发来说可以算是重新开发了一个数据库,不让开发去过多关心数据库的特性,直接在hibernate基础上进行开发,执行上分为了sql生成,数据封装等过程,这里花了大量的时间。然而myBatis则比直接,主要是做关联与输出字段之间的一个映射。其中sql基本是已经写好,直接做替换则可,不需要像hibernate那样去动态生成整条sql语句。
    好在hibernate在这阶段已经优化得比较好,没有比myBatis在性能上差异太多,但是在开发效率上,可扩展性上相对myBatis来说好太多。

     

     

    展开全文
  • 价格差不多的两款路由器,小米路由器43g买哪个好?是很多米粉都比较纠结的问题,今天小编就给大家带来这篇小米路由器3G4的区别对比详细评测,还在犹豫买哪个的朋友可先做参考
  • public class soft_07 { ... * 对于StringStringBuffer速度比较 * 使用System.currentTimeMillis()来记录时间 *LTC-2019-9-18 */ public static void main(String[] args) { long t1 =Sys...
    public class soft_07 {
        /**
         * 对于String和StringBuffer的速度比较
         * 使用System.currentTimeMillis()来记录时间
         *LTC-2019-9-18
         */
        public static void main(String[] args) {
    
            long t1 =System.currentTimeMillis();//记录起始时间
            String str="1";
            for (int i = 2; i <100000 ; i++) {//拼接字符串10000次
                str+=String.valueOf(i);
            }
            long t2=System.currentTimeMillis();//记录结束时间
            System.out.println("使用字符串拼接的方式,连接10000次,耗时:"+(t2-t1)/1000+"秒");//两值做差计算消耗时间
            System.out.println("================");
    
            long t3=System.currentTimeMillis();
            StringBuffer sb=new StringBuffer(1);
            for (int i = 2; i <100000 ; i++) {
                sb.append(i);
            }
            long t4=System.currentTimeMillis();
            System.out.println("使用字符串拼接的方式,连接10000次,耗时:"+(t4-t3)/1000+"秒");
    
    
            System.out.println(str);//测试是否拼接成功字符串
            System.out.println(sb);
        }
    }
    
    

    测试结果:
    在这里插入图片描述

    展开全文
  • 红光激光条码扫描枪的区别对比

    千次阅读 2020-08-05 15:29:08
    红光激光条码扫描枪的区别对比  一、发光原理  红光扫描头是指使用的是CCD的红光发光原理,扫描距离一般为8cm以内;激光扫描头是指使用的是LASER激光发光原理,扫描宽度可达25cm。  二、光线比较  红光条码...
  • 通过组织样例、分析源码,比较Java线程使用startrun启动的区别
  • 1、面向对象面向过程的区别 面向过程: 性能高于面向对象,因为面向对象在类调用时需要实例化对象,开销比较大,比较消耗资源,当性能为最重要的考虑因素时,比如:单片机、嵌入式开发一般采用面向过程。 面向对象...
  • ArrayListLinkedList的区别ArrayList的区别ArrayListLinkedList对比ArrayList的源码分析ArrayList的主要成员变量ArrayList的构造函数扩容机制LinkedList的源码分析 ArrayList的区别 Array(数组)是基于索引...
  • 1、MyISAM:默认表类型,它是基于传统ISAM类型,ISAM是Indexed Sequential Access Method (有索引顺序访问方法) 缩写,它是存储记录文件标准方法。不是事务安全,而且不支持外键,如果执行大量select...
  • 原以为这俩算法是一样。。就只看了react,没想到居然不一样。。。这里做一些笔记 react: ...是将旧虚拟dom同一层级key值节点作为一个集合(旧...先遍历新集合,判断有哪一些节点需要添加删除; 再...
  • 两种最常用 HTTP 方法是:GET POST。...下面表格比较了两种 HTTP 方法:GET POST。 GET POST 后退按钮/刷新 无害 数据会被重新提交(浏览器应该告知用户数据会被重新提交)。 书.
  • Linux程序员经常抱怨,自从他们使用了免费开源的系统平台后,作为一名...现在来说一说常用的编辑器,并且我们还会比较一下这些编辑器之间的区别和优缺点,我平时用的编辑器是vim,当然还有很多的编辑器。现在我们就...
  • Redis、mongo、memcahe的对比和区别

    千次阅读 2016-04-22 15:02:43
    从以下几个维度,对redis、memcache、mongoDB 做了对比,欢迎拍砖1.性能 都比较高,性能对我们来说应该都不是瓶颈 总体来讲,TPS()方面redismemcache差不多,要大于mongodb 2.操作便利性 memcache数据结构单一 ...
  • 有一张表目前四万多条数据,我现在需要更新三天以内浏览量,表默认引擎为InnoDB UPDATE note SET skim_num=skim_num + 30 WHERE DATEDIFF(NOW(),created_...在读操作比较频繁应用场景,MYISAM是比较选择,而.
  • 总结:从搜索java关键字来对比百度360浏览器,我们惊奇发现,百度浏览器里面广告销售比较多,而360对于自身360软件中心关联的比较多。但是总而言,百度是全球中文搜索引擎中最强,作为中国人那是再合适...
  • 从本地中读取图片,可以用decodeFileDescriptordecodeFile,至于哪一种方式耗内存情况作了一次简单对比,可能一次选取6张图片数量过少,貌似区别不大,decodeFileDescriptor能节省1.6mb左右: 1、...
  • jquery版本使用的区别和对比

    千次阅读 2014-01-26 18:01:48
     jquery版本区别:  1.3一般功能够  1.4.2一般功能够而且稳定  1.7+比较新特性  2不支持老IE  兼容话最好选 1.x。稳定性就用1.7或者1.4,其中1.4体积相对小  另外更加情况选用1系列还是2系列...
  • JSDNXML的区别比较

    2016-09-22 23:13:54
    1.定义介绍(1).XML定义(2).JSON定义2.XMLJSON优缺点(1).XML优缺点<1>.XML优点<2>.XML缺点(2).JSON优缺点<1>.JSON优点:<2>.JSON缺点3.XMLJSON优缺点对比(1).可读性方面。(2).可扩展性方面。(3)....
  • ComparatorComparable的区别 当需要排序的集合或数组不是单纯的数字型时,通常可以使用Comparator或Comparable,以简单的方式实现对象排序或自定义排序。  一、Comparator  强行对某个对象...
  • VUEREACT两个JavaScript框架都是当下比较受欢迎的,他们两者之间的区别有那些,各自的优缺点是什么,本文将为你呈现。 简单介绍 除非你最近一直不关注前端的发展,不然你肯定听说过由Facebook创建的JavaScript ...
  • 1、ComparableComparator介绍 在java中Intege,Double等基本数据类型Sting都实现了Comparable...(1)类实现Comparable接口重写comparato方法参数进行对比 public class Persion implements Comparable<
  • 网络桥接器交换机明显不同,具有单独功能。网桥是使用相同协议(例如以太网)连接两个LAN点对点连接。交换机是连接多个客户端并选择网络上数据包路径多端口网桥。 每个交换机都是一个网桥,但是网桥并不是...
  • 数据挖掘技术日趋成熟复杂,随着互联网发展以及大批海量数据到来,之前传统依靠spss、SAS等可视化工具实现数据挖掘建模已经越来越不能满足日常需求,依据美国对数据科学家(data scientist)要求,想成为一...
  • Spark Streaming仅仅在吞吐量上比Storm要优秀,但不是所有场景都那么注重吞吐量(集群利用率比较高) 事实上,Storm在实时延迟度上,比Spark Streaming就好多了,前者是纯实时,后者是准实时。而且,Storm事务...
  • VueReact两个JavaScript框架都是当下比较受欢迎的,他们两者之间的区别有哪些,各自的优缺点是什么,本文将为你呈现。· 我已经写出了两个几乎一样的web应用,一个是基于Vue,另一个则基于React,可以方便你在看...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,944
精华内容 777
关键字:

对比和比较的区别