数据库数据在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;
}
}
}

数据库数据在Java占用内存简单估算的更多相关文章

  1. php 因循环数据 赋值变量 占用内存太大 提示错误

    Fatal error: Allowed memory size of 134217728 bytes exhausted 网上很多解决方法:就简单记录下 一个csv导入功能 由于数据太多 占用内存太 ...

  2. 关于Java占用内存的研究

    最近对程序占用内存方面做了一些优化,取得了不错的效果,总结了一些经验简要说一下,相信会对大家写出优质的程序有所帮助下面的论述针对32位系统,对64位系统不适用,后叙 经常你写了一个程序,一测试,功能没 ...

  3. 查看java进程内存简单示例

    分析工具 1.jps 显示指定系统内的所有JVM进程 2.jstat 收集JVM各方面的运行数据 3.jinfo  显示JVM配置信息 4.jmap  堆快照 5.jhat  分析headdump文件 ...

  4. java构造器级简单内存分析

    java构造器的使用(基础篇) 构造方法也叫构造器,是创建对象时执行的特殊方法,一般用于初始化新对象的属性. 基本定义语法: 访问控制符 构造方法名([参数列表]){ 方法体 } 注:"访问 ...

  5. Delphi数据库数据用文件流方式快速写入Excel文件

    在开发数据库应用程序中,经常要将类型相同的数据导出来,放到Excel文件中,利用Excel强大的编辑功能,对数据作进一步的加工处理.这有许多的方法,我们可以使用OLE技术,在Delphi中创建一个自动 ...

  6. JVM基础系列第6讲:Java 虚拟机内存结构

    看到这里,我相信大家对于一个 Java 源文件是如何变成字节码文件,以及字节码文件的含义已经非常清楚了.那么接下来就是让 Java 虚拟机运行字节码文件,从而得出我们最终想要的结果了.在这个过程中,J ...

  7. 使用Java编写一个简单的Web的监控系统cpu利用率,cpu温度,总内存大小

    原文:http://www.jb51.net/article/75002.htm 这篇文章主要介绍了使用Java编写一个简单的Web的监控系统的例子,并且将重要信息转为XML通过网页前端显示,非常之实 ...

  8. Java程序内存分析:使用mat工具分析内存占用

    国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html内部邀请码:C8E245J (不写邀请码,没有现金送)国内私 ...

  9. docker容器内存占用 之 系统cache,docker下java的内存该如何配置

    缘起: 监控(docker stats)显示容器内存被用完了,进入容器瞅了瞅,没有发现使用内存多的进程,使用awk等工具把容器所有进程使用的内存加起来看看,距离用完还远了去了,何故? 分析: 该不会d ...

随机推荐

  1. React 篇 Search Bar and content Table

    我们要构建一个模块,其中包含一个内容显示的表格,然后上面有一个提供Search的栏位,并对Search中输入栏进行监听,当有改变的时候,触发Search然后对内容表中的内容进行过滤. Demo Lin ...

  2. Appium基于python unittest自动化测试并生成html测试报告

    本文基于python单元测试框架unittest完成appium自动化测试,生成基于html可视化测试报告 代码示例: #利用unittest并生成测试报告 class Appium_test(uni ...

  3. 联想 S5 Pro(L78041)免解锁BL 免rec 保留数据 ROOT Magisk Xposed 救砖 ZUI 5.0.123

    >>>重点介绍<<< 第一:本刷机包可卡刷可线刷,刷机包比较大的原因是采用同时兼容卡刷和线刷的格式,所以比较大第二:[卡刷方法]卡刷不要解压刷机包,直接传入手机后用 ...

  4. 远程图形界面:VncServer与KDE桌面远程连接

           强烈不建议putty+xming的工作方式,太慢了,且界面也不是特别友好.        原文:vncserver与KDE远程连接        建议:不过还是建议使用Xshell,使用 ...

  5. HDU_1505_矩阵中的最大矩形_dp

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1505 City Game Time Limit: 2000/1000 MS (Java/Others) ...

  6. 华登区块狗系统APP开发

    华登区块狗系统开发,陈翎:{.l8O..285l..l22O.}华登区块狗软件开发,华登区块狗APP开发,华登区块狗模式开发,华登区块狗现成源码,狗狗集市理财模式开发 华登区块狗是什么?华登区块狗ap ...

  7. 迭代器,生成器(generator)和Promise的“微妙”关系

    需要Promise源码版的朋友:传送链接 本文主要讲述(iterator)和生成器*/yield之间的联系和各自的用法,以及生成器的高配版本aysnc/await的使用. 大纲: 迭代器(iterat ...

  8. jQuery元素节点的插入

    jquery插入节点的的方法,总的来说有8种,但是只要学会了其中的两个就能理解全部了, 这里我们学习append()和appendTo()两个方法: append()方法是向元素的内部追加内容: &l ...

  9. 记一些关于acm的小知识(自用,粗糙,勿点呀)

    #define INF 0x7ffffff,定义一个很大的数

  10. mysql如何将一个字段多个类型串成一个字符串?

    结论 先说结论,可以使用group_concat group by的组合实现多行变一行,将一个字段的多个类型串成一个字段 需求: 如题,一个字段如电影类别,一部电影可以是多个类别,如喜剧.动作片等,其 ...