需要把这个文件的每一行内容按照列去一起存到数据库里。
由于写代码的人偷懒,想一次解析完毕后一股脑全塞到数据库里。所以,他弄了个 Map,Map 的 Key 是相同的列名,Value是每一行解析过的内容。
而这样写代码的结果就是,一行对应了一个有三个条目的 HashMap。如果文件有十几万行,就有十几万的 HashMap。然后,这些 HashMap 再存到一个列表里,再把这个列表放到一个叫做 xxxCache 的 HashMap 中。
示意代码如下:
public class ParseFile4OOM { public static void main(String[] args) { List<Map<String, String>> lst = new ArrayList<>(); for (int i = 0; i < 100000; i++) { Map<String, String> map = new HashMap<>(); map.put("Column1", "Content1"); map.put("Column2", "Content2"); map.put("Column3", "Content3"); lst.add(map); } Map<String, List<Map<String, String>>> contentCache = new HashMap<>(); contentCache.put("contents", lst); } }那对这种情况怎么办呢?代码还不能大动,只能优化。
那时,我们已经用了 JDK8 了,引入了 String 常量池。同时,Hashmap 在这个业务场景下,容积是固定的,所以,就不应该给它多分配空间,就固定死为 3。
优化后,代码如下:
public class ParseFile4OOM { public static void main(String[] args) { List<Map<String, String>> lst = new ArrayList<>(); for (int i = 0; i < 100000; i++) { Map<String, String> map = new HashMap<>(3); map.put("Column1".intern(), "Content1".intern()); map.put("Column2".intern(), "Content2".intern()); map.put("Column3".intern(), "Content3".intern()); lst.add(map); } Map<String, List<Map<String, String>>> contentCache = new HashMap<>(); contentCache.put("contents".intern(), lst); } }把优化后的代码上线,错误搞定了!
所以,在这个阶段就非得把 JVM 吃透不可了。吃透原理就必须靠看书了。
周志明的《深入理解 JAVA 虚拟机》是必须的了,但是还不够。
《Oracle JRockit: The Definitive Guide》这本书我也建议读一读,虽然老了,但是里面的很多内容,尤其前四章,对 JVM 原理真的快讲透了。对 JVM 是如何弹性伸缩去平衡资源和性能关系的,娓娓道来,让我醍醐灌顶,编程视野一下子打开了很多。
至此,不同阶段的学习方法讲完了。
总的来说,JVM 知识广博复杂,如果想要掌握,不能一蹴而就。而且咱们程序员不容易,需要学的知识太多,然而咱们的精力却是有限的。
所以,对于 JVM 原理来说,假设有些知识点眼前看不懂,用不上,可以先暂时放一放,做到精准学习,把省下来的精力用在别的知识甚至自己的生活上,更有意义。
看完如果觉得有收获,希望能随手点个赞。
你好,我是四猿外。
一家上市公司的技术总监,管理的技术团队一百余人。
我从一名非计算机专业的毕业生,转行到程序员,一路打拼,一路成长。
我会把自己的成长故事写成文章,把枯燥的技术文章写成故事。
欢迎关注我的公众号。