搜索
首页数据库mysql教程数据库数据在Java占用内存简单估算

数据库数据在Java占用内存简单估算 结论: 1.数据库记录放在JAVA里,用对象(ORM一般的处理方式)需要4倍左右的内存空间,用HashMap这种KV保存需要10倍空间; 2.如果你主要数据是text大文本,那空间一般可以按2倍估算。 以上是一个通用数据测试结论,估大家参考

数据库数据在Java占用内存简单估算

结论:

1.数据库记录放在JAVA里,用对象(ORM一般的处理方式)需要4倍左右的内存空间,用HashMap这种KV保存需要10倍空间;

2.如果你主要数据是text大文本,那空间一般可以按2倍估算。

以上是一个通用数据测试结论,估大家参考。

数据库记录占用的空间大小比较好算,比如一个int占用4字节,bigint占用8字节,date占用3字节,datetime占用8字节,varchar是变长字节等。如果不想精确计算,在数据库中通过统计信息也可以比较轻松的知道表总共占用的空间及每条记录平均行长。

当我们用JDBC访问数据库时,经常会被问到内存溢出的问题,由于java是面向对象的语言,用JVM来自动内存回收,不能按普通方法计算内存,本文给出一个估算内存的思路和参考答案

先给出普通JDBC中数据库对象与内存的映射关系

MySQL

Oracle

JDBC

Int

 

Integer

Int unsigned

 

Long

BigInt

 

Long

BigInt unsigned

 

BigInteger

Decimal

Number

BigDecimal

Varchar

Varchar2

String

Date

 

Date

Datetime

Date

Timestamp

Timestamp

Timestamp

Timestamp

Clob

Clob

String

Blob

blob

Byte[]

Text

Clob

String

float

binary_float

float

double

binary_double

double

上面这个比较好理解,接下来我们需要JAVA常用对象的内存占用空间,这个可以通过JDK 5 开始提供的Instrumentation 接口来完成,也可以通过开源的sizeOf.jar 来测试,笔者是通过sizeOf.jar验证的。测试结果数据如下:

对象

64位 JVM 压缩指针

 64位 JVM 非压缩指针

Integer

16

24

Long

24

24

Object

16

16

Date

24

32

Timestamp

32

40

String_0

48

64

String_1

56

72

String_10

72

88

String_100

248

264

StringBuilder

24

32

BigDecimal

40

48

BigInteger

64

80

HashMap

128

216

HashMap_0

72

96

HashMap_100

576

1112

HashMap_10000

65600

131160

ArrayList

80

144

ArrayList_0

40

64

ArrayList_100

440

864

ArrayList_10000

40040

80064

LinkedList

48

80

LinkedHashMap

96

144

ClassA

32

40

ClassB

40

48

ClassC

40

56

由于现在主机一般都是64位, 64位JVM从JDK1.6.45开始,当JVM最大内存小于32GB时,自动打开压缩指针特性,这样对象的内存占用空间少很多,由上表可以看出,至少减少1/3的空间。

下面我们结合数据库数据来测试

假如mysql数据库有一张emp表,结构如下:

CREATE TABLE `emp` (
  `id` int(11) NOT NULL,
  `create_time` datetime DEFAULT NULL,
  `modify_time` datetime DEFAULT NULL,
  `name` varchar(16) DEFAULT NULL,
  `address` varchar(256) DEFAULT NULL,
  `age` smallint(6) DEFAULT NULL,
  `height` decimal(10,2) DEFAULT NULL,
  `weight` decimal(10,2) DEFAULT NULL,
  `phone` varchar(20) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

样本数据如下:

hm.put("id", 1988);
hm.put("createTime", new Date());
hm.put("modifyTime", new Date());
hm.put("name", "张三丰");
hm.put("address","浙江杭州市西湖大道188号808室");
hm.put("age",88);
hm.put("weight",new BigDecimal(88));
hm.put("height",new BigDecimal(188));
hm.put("phone","1388888888");

按上面样本数据计算,有效数据约80字节,在MySQL里占用空间约120字节

在java里转换为HashMap和Emp对象测试空间如下

对象

64位 JVM 压缩指针

 64位 JVM 非压缩指针

HashMap_empty

128

216

HashMap_full

1360

1832

Emp_empty

72

112

Emp_full

464

600

从上面测试结果看,数据到JAVA里占用的空间增加了许多,在64位压缩指针下,如果存到HashMap,需要1360字节,空间是数据库约11.3倍,如果存为Emp普通对象,需要464字节,是数据库的3.8倍。

如果我们是一个分页从数据库读取emp信息,每页显示50条记录,用List保存,HashMap需要68KB,emp对象需要23KB。

根据这个简单测试,我们可以总结一个结论:

数据库记录放在JAVA里,用对象(ORM一般的处理方式)需要4倍左右的内存空间,用HashMap这种KV保存需要10倍空间。

如果你的数据和参考数据差异非常大,如主要数据text大文本,那空间一般可以简单的按2倍估算。

以上是一个通用数据测试结论,估大家参考。

下面是测试代码:

import net.sourceforge.sizeof.SizeOf;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.*;

public class TestSize {
    static {
        SizeOf.skipStaticField(true); //java.sizeOf will not compute static fields
        //SizeOf.skipFinalField(true); //java.sizeOf will not compute final fields
        //SizeOf.skipFlyweightObject(true); //java.sizeOf will not compute well-known flyweight objects
    }
    public static void main(String[] args) throws SQLException, IOException, IllegalAccessException {
        TestSize ts=new TestSize();
        ts.testObjectSize();
        ts.testDataSize();
        System.out.println("ok");
    }

    public void testObjectSize() {
        System.out.println("Integer:"+SizeOf.deepSizeOf(new Integer(56)));
        System.out.println("Long:"+SizeOf.sizeOf(new Long(56L)));
        System.out.println("Object:"+SizeOf.sizeOf(new Object()));
        System.out.println("Date:"+SizeOf.sizeOf(new Date()));
        System.out.println("Timestamp:"+SizeOf.sizeOf(new Timestamp(System.currentTimeMillis())));
        System.out.println("String_0:"+SizeOf.deepSizeOf(new String()));
        System.out.println("String_1:"+SizeOf.deepSizeOf(new String("1")));
        System.out.println("String_10:"+SizeOf.deepSizeOf(new String("0123456789")));
        System.out.println("String_100:"+SizeOf.deepSizeOf("0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789"));
        System.out.println("StringBuilder:"+SizeOf.deepSizeOf(new StringBuilder()));
        System.out.println("BigDecimal:"+SizeOf.deepSizeOf(new BigDecimal("34535643.23")));
        System.out.println("BigInteger:"+SizeOf.deepSizeOf(new BigInteger("34535643")));
        System.out.println("HashMap:"+SizeOf.deepSizeOf(new HashMap()));
        System.out.println("HashMap_0:"+SizeOf.deepSizeOf(new HashMap(0)));
        System.out.println("HashMap_100:"+SizeOf.deepSizeOf(new HashMap(100)));
        System.out.println("HashMap_10000:" + SizeOf.deepSizeOf(new HashMap(10000)));
        System.out.println("ArrayList:"+SizeOf.deepSizeOf(new ArrayList()));
        System.out.println("ArrayList_0:"+SizeOf.deepSizeOf(new ArrayList(0)));
        System.out.println("ArrayList_100:"+SizeOf.deepSizeOf(new ArrayList(100)));
        System.out.println("ArrayList_10000:"+SizeOf.deepSizeOf(new ArrayList(10000)));
        System.out.println("LinkedList:"+SizeOf.deepSizeOf(new LinkedList<Object>()));
        System.out.println("LinkedHashMap:"+SizeOf.deepSizeOf(new LinkedHashMap<Object,Object>()));

        System.out.println("ClassA:" + SizeOf.deepSizeOf(new ClassA()));
        System.out.println("ClassB:"+SizeOf.deepSizeOf(new ClassB()));
        System.out.println("ClassC:"+SizeOf.deepSizeOf(new ClassC()));

    }
    public void testDataSize() throws IOException, IllegalAccessException {
        HashMap hm=new HashMap();
        System.out.println("HashMap_empty:"+SizeOf.deepSizeOf(hm));
        hm.put("id", 1988);
        hm.put("createTime", new Date());
        hm.put("modifyTime", new Date());
        hm.put("name", "张三丰");
        hm.put("address","浙江杭州市西湖大道188号808室");
        hm.put("age",88);
        hm.put("weight",new BigDecimal(88));
        hm.put("height",new BigDecimal(188));
        hm.put("phone","1388888888");
        System.out.println("HashMap_full:" + SizeOf.deepSizeOf(hm));
        Emp emp=new Emp();
        System.out.println("Emp_empty:"+SizeOf.deepSizeOf(emp));
        emp.setId(1988);
        emp.setCreateTime(new Timestamp(System.currentTimeMillis()));
        emp.setModifyTime(new Timestamp(System.currentTimeMillis()));
        emp.setName("张三丰");
        emp.setAddress("浙江杭州市西湖大道188号808室");
        emp.setAge(28);
        emp.setWeight(new BigDecimal("88"));
        emp.setHeight(new BigDecimal("188"));
        emp.setPhone("13888888888");
        System.out.println("Emp_full:"+SizeOf.deepSizeOf(emp));
    }
    class ClassA{
    }
    class ClassB extends  ClassA{
    }
    class ClassC extends  ClassB{
    }
    class Emp{
        private Integer id;
        private Timestamp createTime;
        private Timestamp modifyTime;
        private String name;
        private String address;
        private Integer age;
        private BigDecimal height;
        private BigDecimal weight;
        private String phone;

        public Integer getId() {
            return id;
        }

        public void setId(Integer id) {
            this.id = id;
        }

        public Timestamp getCreateTime() {
            return createTime;
        }

        public void setCreateTime(Timestamp createTime) {
            this.createTime = createTime;
        }

        public Timestamp getModifyTime() {
            return modifyTime;
        }

        public void setModifyTime(Timestamp modifyTime) {
            this.modifyTime = modifyTime;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getAddress() {
            return address;
        }

        public void setAddress(String address) {
            this.address = address;
        }

        public Integer getAge() {
            return age;
        }

        public void setAge(Integer age) {
            this.age = age;
        }

        public BigDecimal getHeight() {
            return height;
        }

        public void setHeight(BigDecimal height) {
            this.height = height;
        }

        public BigDecimal getWeight() {
            return weight;
        }

        public void setWeight(BigDecimal weight) {
            this.weight = weight;
        }

        public String getPhone() {
            return phone;
        }

        public void setPhone(String phone) {
            this.phone = phone;
        }
    }
}
声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
解释InnoDB缓冲池及其对性能的重要性。解释InnoDB缓冲池及其对性能的重要性。Apr 19, 2025 am 12:24 AM

InnoDBBufferPool通过缓存数据和索引页来减少磁盘I/O,提升数据库性能。其工作原理包括:1.数据读取:从BufferPool中读取数据;2.数据写入:修改数据后写入BufferPool并定期刷新到磁盘;3.缓存管理:使用LRU算法管理缓存页;4.预读机制:提前加载相邻数据页。通过调整BufferPool大小和使用多个实例,可以优化数据库性能。

MySQL与其他编程语言:一种比较MySQL与其他编程语言:一种比较Apr 19, 2025 am 12:22 AM

MySQL与其他编程语言相比,主要用于存储和管理数据,而其他语言如Python、Java、C 则用于逻辑处理和应用开发。 MySQL以其高性能、可扩展性和跨平台支持着称,适合数据管理需求,而其他语言在各自领域如数据分析、企业应用和系统编程中各有优势。

学习MySQL:新用户的分步指南学习MySQL:新用户的分步指南Apr 19, 2025 am 12:19 AM

MySQL值得学习,因为它是强大的开源数据库管理系统,适用于数据存储、管理和分析。1)MySQL是关系型数据库,使用SQL操作数据,适合结构化数据管理。2)SQL语言是与MySQL交互的关键,支持CRUD操作。3)MySQL的工作原理包括客户端/服务器架构、存储引擎和查询优化器。4)基本用法包括创建数据库和表,高级用法涉及使用JOIN连接表。5)常见错误包括语法错误和权限问题,调试技巧包括检查语法和使用EXPLAIN命令。6)性能优化涉及使用索引、优化SQL语句和定期维护数据库。

MySQL:初学者的基本技能MySQL:初学者的基本技能Apr 18, 2025 am 12:24 AM

MySQL适合初学者学习数据库技能。1.安装MySQL服务器和客户端工具。2.理解基本SQL查询,如SELECT。3.掌握数据操作:创建表、插入、更新、删除数据。4.学习高级技巧:子查询和窗口函数。5.调试和优化:检查语法、使用索引、避免SELECT*,并使用LIMIT。

MySQL:结构化数据和关系数据库MySQL:结构化数据和关系数据库Apr 18, 2025 am 12:22 AM

MySQL通过表结构和SQL查询高效管理结构化数据,并通过外键实现表间关系。1.创建表时定义数据格式和类型。2.使用外键建立表间关系。3.通过索引和查询优化提高性能。4.定期备份和监控数据库确保数据安全和性能优化。

MySQL:解释的关键功能和功能MySQL:解释的关键功能和功能Apr 18, 2025 am 12:17 AM

MySQL是一个开源的关系型数据库管理系统,广泛应用于Web开发。它的关键特性包括:1.支持多种存储引擎,如InnoDB和MyISAM,适用于不同场景;2.提供主从复制功能,利于负载均衡和数据备份;3.通过查询优化和索引使用提高查询效率。

SQL的目的:与MySQL数据库进行交互SQL的目的:与MySQL数据库进行交互Apr 18, 2025 am 12:12 AM

SQL用于与MySQL数据库交互,实现数据的增、删、改、查及数据库设计。1)SQL通过SELECT、INSERT、UPDATE、DELETE语句进行数据操作;2)使用CREATE、ALTER、DROP语句进行数据库设计和管理;3)复杂查询和数据分析通过SQL实现,提升业务决策效率。

初学者的MySQL:开始数据库管理初学者的MySQL:开始数据库管理Apr 18, 2025 am 12:10 AM

MySQL的基本操作包括创建数据库、表格,及使用SQL进行数据的CRUD操作。1.创建数据库:CREATEDATABASEmy_first_db;2.创建表格:CREATETABLEbooks(idINTAUTO_INCREMENTPRIMARYKEY,titleVARCHAR(100)NOTNULL,authorVARCHAR(100)NOTNULL,published_yearINT);3.插入数据:INSERTINTObooks(title,author,published_year)VA

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热工具

MinGW - 适用于 Windows 的极简 GNU

MinGW - 适用于 Windows 的极简 GNU

这个项目正在迁移到osdn.net/projects/mingw的过程中,你可以继续在那里关注我们。MinGW:GNU编译器集合(GCC)的本地Windows移植版本,可自由分发的导入库和用于构建本地Windows应用程序的头文件;包括对MSVC运行时的扩展,以支持C99功能。MinGW的所有软件都可以在64位Windows平台上运行。

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

将Eclipse与SAP NetWeaver应用服务器集成。

Dreamweaver Mac版

Dreamweaver Mac版

视觉化网页开发工具

EditPlus 中文破解版

EditPlus 中文破解版

体积小,语法高亮,不支持代码提示功能

安全考试浏览器

安全考试浏览器

Safe Exam Browser是一个安全的浏览器环境,用于安全地进行在线考试。该软件将任何计算机变成一个安全的工作站。它控制对任何实用工具的访问,并防止学生使用未经授权的资源。