`
endual
  • 浏览: 3509290 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

JVM 数据存储与逻辑

    博客分类:
  • jvm
 
阅读更多

    Java虚拟机中,数据类型可以分为两类:基本类型和引用类型。基本类型的变量保存原始值,即:他代表的值就是数值本身;而引用类型的变量保存引用值。“引用值”代表了某个对象的引用,而不是对象本身,对象本身存放在这个引用值所表示的地址的位置。

       基本类型包括:byte, short, int, long, char, float, double, Boolean, returnAddress

       引用类型包括:类类型,接口类型和数组。

       堆与栈

       堆和栈是程序运行的关键,很有必要把他们的关系说清楚。栈是运行时的单位,而堆是存储的单位。

       栈解决程序的运行问题,即程序如何执行,或者说如何处理数据;堆解决的是数据存储的问题,即数据怎么放、放在哪儿。

       在Java中一个线程就会相应有一个线程栈与之对应,这点很容易理解,因为不同的线程执行逻辑有所不同,因此需要一个独立的线程栈。而堆则是所有线程共享 的。栈因为是运行单位,因此里面存储的信息都是跟当前线程(或程序)相关信息的。包括局部变量、程序运行状态、方法返回值等等;而堆只负责存储对象信息。

       为什么要把堆和栈区分出来呢?栈中不是也可以存储数据吗?

       第一 ,从软件设计的角度看,栈代表了处理逻辑,而堆代表了数据。这样分开,使得处理逻辑更为清晰。分而治之的思想。这种隔离、模块化的思想在软件设计的方方面面都有体现。

       第二 ,堆与栈的分离,使得堆中的内容可以被多个栈共享(也可以理解为多个线程访问同一个对象)。这种共享的收益是很多的。一方面这种共享提供了一种有效的数据交互方式(如:共享内存),另一方面,堆中的共享常量和缓存可以被所有栈访问,节省了空间。

       第三 ,栈因为运行时的需要,比如保存系统运行的上下文,需要进行地址段的划分。由于栈只能向上增长,因此就会限制住栈存储内容的能力。而堆不同,堆中的对象是可以根据需要动态增长的,因此栈和堆的拆分,使得动态增长成为可能,相应栈中只需记录堆中的一个地址即可。

       第四 ,面向对象就是堆和栈的完美结合。其实,面向对象方式的程序与以前结构化的程序在执行上没有任何 区别。但是,面向对象的引入,使得对待问题的思考方式发生了改变,而更接近于自然方式的思考。当我们把对象拆开,你会发现,对象的属性其实就是数据,存放 在堆中;而对象的行为(方法),就是运行逻辑,放在栈中。我们在编写对象的时候,其实即编写了数据结构,也编写的处理数据的逻辑。不得不承认,面向对象的 设计,确实很美。

       在Java中,Main函数就是栈的起始点,也是程序的起始点。

       程序要运行总是有一个起点的。同C语言一样,java中的Main就是那个起点。无论什么java程序,找到main就找到了程序执行的入口:)

       堆中存什么?栈中存什么?

       堆中存的是对象。栈中存的是基本数据类型和堆中对象的引用。一个对象的大小是不可估计的,或者说是可以动态变化的,但是在栈中,一个对象只对应了一个4btye的引用(堆栈分离的好处:))。

       为什么不把基本类型放堆中呢?因为其占用的空间一般是1~8个字节——需要空间比较少,而且因为是基本类型,所以不会出现动态增长的情况——长度固定,因 此栈中存储就够了,如果把他存在堆中是没有什么意义的(还会浪费空间,后面说明)。可以这么说,基本类型和对象的引用都是存放在栈中,而且都是几个字节的 一个数,因此在程序运行时,他们的处理方式是统一的。但是基本类型、对象引用和对象本身就有所区别了,因为一个是栈中的数据一个是堆中的数据。最常见的一 个问题就是,Java中参数传递时的问题。

       Java中的参数传递时传值呢?还是传引用?

       要说明这个问题,先要明确两点:

       1. 不要试图与C进行类比,Java中没有指针的概念

       2. 程序运行永远都是在栈中进行的,因而参数传递时,只存在传递基本类型和对象引用的问题。不会直接传对象本身。

       明确以上两点后。Java在方法调用传递参数时,因为没有指针,所以它都是进行传值调用(这点可以参考C的传值调用)。因此,很多书里面都说Java是进行传值调用,这点没有问题,而且也简化的C中复杂性。

       但是传引用的错觉是如何造成的呢?在运行栈中,基本类型和引用的处理是一样的,都是传值,所以,如果是传引用的方法调用,也同时可以理解为“传引用值”的 传值调用,即引用的处理跟基本类型是完全一样的。但是当进入被调用方法时,被传递的这个引用的值,被程序解释(或者查找)到堆中的对象,这个时候才对应到 真正的对象。如果此时进行修改,修改的是引用对应的对象,而不是引用本身,即:修改的是堆中的数据。所以这个修改是可以保持的了。

       对象,从某种意义上说,是由基本类型组成的。可以把一个对象看作为一棵树,对象的属性如果还是对象,则还是一颗树(即非叶子节点),基本类型则为树的叶子 节点。程序参数传递时,被传递的值本身都是不能进行修改的,但是,如果这个值是一个非叶子节点(即一个对象引用),则可以修改这个节点下面的所有内容。

       堆和栈中,栈是程序运行最根本的东西。程序运行可以没有堆,但是不能没有栈。而堆是为栈进行数据存储服务,说白了堆就是一块共享的内存。不过,正是因为堆和栈的分离的思想,才使得Java的垃圾回收成为可能。

       Java中,栈的大小通过-Xss来设置,当栈中存储数据比较多时,需要适当调大这个值,否则会出现java.lang.StackOverflowError异常。常见的出现这个异常的是无法返回的递归,因为此时栈中保存的信息都是方法返回的记录点。

 

分享到:
评论

相关推荐

    MySQL、JVM、RocketMQ、JUC、设计模式、数据结构与算法学习总结.zip

    逻辑结构:描述数据元素之间的逻辑关系,如线性结构(如数组、链表)、树形结构(如二叉树、堆、B树)、图结构(有向图、无向图等)以及集合和队列等抽象数据类型。 存储结构(物理结构):描述数据在计算机中如何...

    【java开发笔记指北】涵盖java、JVM、Spring、常用框架、中间件、数据库等学习笔记集合

    数据结构是计算机存储、组织数据的方式,它涉及到数据的逻辑结构、物理结构以及对数据的基本操作。数据结构的选择会影响到程序的效率、可读性和可维护性。常见的数据结构有数组、链表、栈、队列、树、图等。 算法则...

    kotlin-multiplatform-example:具有JVM和JS目标的准系统Kotlin多平台项目

    假设有一个简单的体系结构,其中server模块是后端JVM应用程序, client是通常的前端Web应用程序,而common模块允许共享数据结构,验证逻辑等。 它还在两个目标平台上都提供了有效的测试设置。 随意将其用于个人和...

    大数据测试——精选推荐.pdf

    性能测试策略 性能测试策略 ⼤数据应⽤性能测试涉及海量的结构化和⾮结构化的数据,与我们平时所⾯对的业务系统有所不同,所以我们需要针对⼤数据应⽤制定特定的测试策略,以应对 海量的数据。 根据上图性能测试执⾏...

    Hadoop硬实战 [(美)霍姆斯著][电子工业出版社][2015.01]_PDF电子书下载 带书签目录 高清完整版.rar )

    5.2 通过压缩提高数据存储效率 技术点25 选择合适的压缩解码器 技术点26 在HDFS、MapReduce、Pig 和Hive 中使用数据压缩 技术点27 在MapReduce、Hive 和Pig 中处理可分割的LZOP 5.3 本章小结 6 诊断和优化...

    Hadoop实战(第2版)

    它为开发者进行数据存储、管理以及分析提供便利的方法。 《Hadoop硬实战》收集了85个问题场景以及解决方案的实战演练。在关键问题领域对基础概念和实战方法做了权衡,例如导入导出、序列化,以及LZO压缩。你将会...

    java核心面试

    每条线程都有自己的工作内存(Working Memory),工作内存中保存的是主存中某些对象成员变量的拷贝,线程对所有对象成员变量的操作都是在工作内存中进行,线程之间无法相互直接访问,变量传递均需要通过主存完成。...

    java核心面试技术点

    每条线程都有自己的工作内存(Working Memory),工作内存中保存的是主存中某些对象成员变量的拷贝,线程对所有对象成员变量的操作都是在工作内存中进行,线程之间无法相互直接访问,变量传递均需要通过主存完成。...

    LogicNG:下一代逻辑库

    介绍 LogicNG是一个Java库,用于创建,处理和求解布尔和伪布尔公式。... 与JVM上逻辑库的其他实现相比,这是巨大的内存和性能改进。 用法 LogicNG在Maven中央存储库中发布。 要添加它,只需添加 < dependency>

    【白雪红叶】JAVA学习技术栈梳理思维导图.xmind

    关于java程序员发展需要学习的路线整理集合 技术 应用技术 计算机基础知识 cpu mem disk ... 线程,进程 第三方库 ... 数据结构 ... JVM级别 ... 大数据与nosql ... JVM 多线程与并发 ... 数据结构与算法 各种工具

    Spring.3.x企业应用开发实战(完整版).part2

    11.3.4 以块数据方式读取Lob数据 11.3.5 以流数据方式读取Lob数据 11.4 自增键和行集 11.4.1 自增键的使用 11.4.2 如何规划主键方案 11.4.3 以行集返回数据 11.5 其他类型的JDBCTemplate 11.5.1 ...

    Spring3.x企业应用开发实战(完整版) part1

    11.3.4 以块数据方式读取Lob数据 11.3.5 以流数据方式读取Lob数据 11.4 自增键和行集 11.4.1 自增键的使用 11.4.2 如何规划主键方案 11.4.3 以行集返回数据 11.5 其他类型的JDBCTemplate 11.5.1 ...

    Java开发实战1200例(第1卷).(清华出版.李钟尉.陈丹丹).part3

    实例186 泛型方法与数据查询 236 实例187 泛型化方法与最小值 238 实例188 泛型化接口与最大值 239 实例189 使用通配符增强泛型 240 实例190 泛型化的折半查找法 241 第9章 编程常用类 343 9.1 Calendar类的使用 244...

    aurora:Aurora 是 Java Scala 用于分片 IO 的库

    数据源分片功能预定义的数据源组和解析器可以根据提示对数据源进行解析(数据源的连接转换需要单独的逻辑,后面会详细介绍)。 表名/分片功能预定义的解析器可以根据提示解析表名。 使用方法(针对用户) 数据源分片...

    JAVA_API1.6文档(中文)

    java.awt.dnd Drag 和 Drop 是一种直接操作动作,在许多图形用户界面系统中都会遇到它,它提供了一种机制,能够在两个与 GUI 中显示元素逻辑相关的实体之间传输信息。 java.awt.event 提供处理由 AWT 组件所激发的...

    125集专攻JAVA基础 JAVA零基础入门学习视频教程 动力节点JAVA视频教程.txt

    北京动力节点-Java编程零基础教程-037-Java基本语法-数据存储.avi 北京动力节点-Java编程零基础教程-038-Java基本语法-十进制到二进制转换.avi 北京动力节点-Java编程零基础教程-039-Java基本语法-二进制到十进制...

    react-company:React式Web应用程序的示例。 Java。 Spring 5.React流。 码头工人

    例如,在React性组件从数据库扩展到HTTP响应的管道中,当HTTP连接太慢时,数据存储库也可能变慢或完全停止,直到释放网络容量。 React式编程还导致从命令式逻辑到声明式异步逻辑的重大转变。 与使用Java 8中的...

Global site tag (gtag.js) - Google Analytics