实验目的
- 测试时间序列ID化后内存空间占用
- 测试SHA256 java版本性能
实验场景
每时间序列标识长度为200字节,共有100万时间序列,其中measurement占用20字节
每个时间序列通过SHA256算法ID化成32字节的ID,使用哈希表存储,键为ID,值为数据类型及磁盘指针
内存占用
理论分析
ID占用32字节,数据类型占用1字节,磁盘指针占用4字节
纯数据内存 = 1M * (32 + 1 + 4) = 37MB
必须的JAVA对象(HashMap Node对象,Key对象, Value对象)= 1M * (32 + 16 + 16) = 64MB
理论最小空间占用 = 纯数据内存 + 必须的JAVA对象 = 37 + 64 = 101 MB
实验结果
实际内存占用:104MB
原因分析
JVM虚拟机具有字节对齐的特点,1字节的数据类型被对齐为4字节,故占用空间多了3MB
实验代码
Key
public class Key { byte b1; byte b2; byte b3; byte b4; byte b5; byte b6; byte b7; byte b8; byte b9; byte b10; byte b11; byte b12; byte b13; byte b14; byte b15; byte b16; byte b17; byte b18; byte b19; byte b20; byte b21; byte b22; byte b23; byte b24; byte b25; byte b26; byte b27; byte b28; byte b29; byte b30; byte b31; byte b32; }
Value
public class Value { int pos; byte type; public Value(int pos, byte type) { this.pos = pos; this.type = type; } }
Main
public class Main { private static final int size = 10_000_00; public static void main(String[] args) throws InterruptedException { HashMap<Key, Value> map = new HashMap<>(); // System.out.println(Integer.toBinaryString(-1)); for (int i = 1; i <= size; i++) { map.put(new Key(), new Value(1,(byte) 1)); } System.out.println("finish " + map.size()); Thread.sleep(1000000); } }
SHA256算法吞吐量
吞吐量
408次SHA256每毫秒
实验代码
import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Random; public class SpeedMain { private static MessageDigest md; private static final int size = 1_000_000; private static final int pathSize = 200; public static void main(String[] args) throws NoSuchAlgorithmException { md = MessageDigest.getInstance("SHA-256"); StringBuilder path = new StringBuilder(); Random random = new Random(); for (int i = 0; i < pathSize; i++) { path.append(random.nextInt(9)); } long curTime = System.nanoTime(); for(int i = 0; i < size; i++){ cal(path.toString()); md.reset(); } long finishTime = System.nanoTime(); System.out.println("Throughput: " + size / ((finishTime - curTime) / 1_000_000) + " num / ms."); } private static byte[] cal(String s){ return md.digest(s.getBytes()); } }
新实现下的内存占用
测试数据量
10万设备,每个设备下100个测点
数据结构
HashMap<DeviceID, HashMap<String, SchemaEntry>>
内存占用
类 | 内存占用 |
---|---|
Hashmap Node | 3.2GB |
Hashmap Node[] | 1.2GB |
DeviceID | 48MB |
HashMap | 48MB |
Schema Entry | 4GB |
String | 2.4G |
char[] | 3.2G* |
总计 | 14.096GB |
*java中char类型占用两个字节,长度为10的string占用20字节,外加8字节引用,4字节数组长度