0%
这是一片思考的空间 -- arthinking
Spring 重构&代码整洁之道 软件设计 JVM 并发编程 数据结构与算法 分布式 存储 网络 微服务 设计模式
Java技术栈 - 涉及Java技术体系

IKAnalyzer词典占用内存大小分析

这里还是使用搜狗的扩展词库

扩展词典添加搜狗词库:

http://pinyin.sogou.com/dict/cell.php?id=11640

词条

大小

392790个

13737KB

先直接用java.lang.Runtime类中的freeMemory(),totalMemory(),maxMemory ()这几个方法

进行计算。

先把这92790个放入到ext.dic文件中。

加上IKAnalyzer默认加载的这两个词典:

org/wltea/analyzer/dic/main2012.dic 275713个

org/wltea/analyzer/dic/quantifier.dic 316个

总格的词条是66W多。

执行如下代码:

public static void main(String[] args){
calculateMem();
}
public static void calculateMem(){
System.out.println("初始化内存");
System.out.println("空闲内存:" + Runtime.getRuntime().freeMemory());
System.out.println("已获取到的内存:" + Runtime.getRuntime().totalMemory());
System.out.println("能够获得的最大内存:" +Runtime.getRuntime().maxMemory());
System.gc();
Dictionary.initial(DefaultConfig.getInstance());
long total = Runtime.getRuntime().totalMemory(); // 返回总的内存数
long size = Runtime.getRuntime().freeMemory(); // 返回当前的剩余内存数
System.out.println("Memory used: " + (total - size));
}

执行结果如下:

初始化内存

空闲内存:15965080

已获取到的内存:16252928

能够获得的最大内存:518979584

加载扩展词典:ext.dic

加载扩展停止词典:stopword.dic

Memory used: 95027120B

结果是90.62M

接下来使用Instrumentation的getObjectSize方法进行计算下:

public class CalculateDictionarySize {
public static void main(String[] args){
Dictionary.initial(DefaultConfig.getInstance());
System.out.print(SizeOfAgent.fullSizeOf(Dictionary.getSingleton()) + "B");
}
}

编写MANIFEST.MF文件:

Manifest-Version: 1.0
Ant-Version: Apache Ant 1.6.1
Created-By: 1.5.0_06-b05 (Sun Microsystems Inc.)
Main-Class: com.itzhai.test.CalculateDictionarySize
Class-Path: lib/IKAnalyzer2012_u6.jar
Premain-Class: com.itzhai.test.SizeOfAgent
Boot-Class-Path:
Can-Redefine-Classes: false

包结构如下:

20140608-java01

SizeOfAgent的写法参考这里:

http://www.itzhai.com/java-object-memory-calculate-method.html

打包成Jar文件之后,到命令行中执行:

java -javaagent:sizeOfAgent.jar com.itzhai.test.CalculateDictionarySize

结果如下:

20140608-java02

73.48M

也就是说66W多个字条占用了73.48M的内存。

IKAnalyzer的存储结构:

IKAnalyzer是以字典树的方式把字典载入内存中的:

词典管理类为Dictionary,有三种词典:主词典,停用词词典,量词词典,这三种词典都是对应为一个DictSegment对象的,而DictSegment对象时树形结构的,每一个子节点又可以是一个DictSegment对象。

节点的存储方式:以数组(DictSegment[])或者Map(Map<Character, DictSegment)存储的,按照如下规则选择存储方式

  • 如果子节点数量小于等于ARRAY_LENGTH_LIMIT,则采用数组存储
  • 如果子节点数量大于ARRAY_LENGTH_LIMIT,则采用Map存储。

欢迎关注我的其它发布渠道

订阅IT宅
内功修炼
Java技术栈
Java架构杂谈是IT宅精品文章公众号,欢迎订阅:
📄 网络基础知识:两万字长文50+张趣图带你领悟网络编程的内功心法 📄 HTTP发展史:三万长文50+趣图带你领悟web编程的内功心法 📄 HTTP/1.1:可扩展,可靠性,请求应答,无状态,明文传输 📄 HTTP/1.1报文详解:Method,URI,URL,消息头,消息体,状态行 📄 HTTP常用请求头大揭秘 📄 HTTPS:网络安全攻坚战 📄 HTTP/2:网络安全传输的快车道 📄 HTTP/3:让传输效率再一次起飞 📄 高性能网络编程:图解Socket核心内幕以及五大IO模型 📄 高性能网络编程:三分钟短文快速了解信号驱动式IO 📄 高性能网络编程:彻底弄懂IO复用 - IO处理杀手锏,带您深入了解select,poll,epoll 📄 高性能网络编程:异步IO:新时代的IO处理利器 📄 高性能网络编程:网络编程范式 - 高性能服务器就这么回事 📄 高性能网络编程:性能追击 - 万字长文30+图揭秘8大主流服务器程序线程模型
📄 Java内存模型:如果有人给你撕逼Java内存模型,就把这些问题甩给他 📄 一文带你彻底理解同步和锁的本质(干货) 📄 AQS与并发包中锁的通用实现 📄 ReentrantLock介绍与使用 📄 ReentrantReadWriteLock介绍与使用 📄 ReentrantLock的Condition原理解析 📄 如何优雅的中断线程 📄 如何优雅的挂起线程 📄 图解几个好玩的并发辅助工具类 📄 图解BlockingQueue阻塞队列
📄 消息队列那么多,为什么建议深入了解下RabbitMQ? 📄 高并发异步解耦利器:RocketMQ究竟强在哪里? 📄 Kafka必知必会18问:30+图带您看透Kafka
📄 洞悉MySQL底层架构:游走在缓冲与磁盘之间 📄 SQL运行内幕:从执行原理看调优的本质 📄 洞悉Redis技术内幕:缓存,数据结构,并发,集群与算法