JVM内存结构有哪些?HashMap和HashTable的区别?
JVM内存结构
JVM内存主要分为以下几个区域:
-
程序计数器(Program Counter Register)
-
线程私有,记录当前线程执行的字节码行号指示器
-
唯一一个不会出现OOM的内存区域
-
-
Java虚拟机栈(Java Virtual Machine Stacks)
-
线程私有,生命周期与线程相同
-
存储栈帧(局部变量表、操作数栈、动态链接、方法出口等)
-
可能出现StackOverflowError和OutOfMemoryError
-
-
本地方法栈(Native Method Stack)
-
为Native方法服务
-
同样可能出现StackOverflowError和OutOfMemoryError
-
-
Java堆(Java Heap)
-
线程共享,存放对象实例
-
GC主要管理区域,可分为新生代(Eden、Survivor)、老年代
-
可能出现OutOfMemoryError
-
-
方法区(Method Area)
-
线程共享,存储类信息、常量、静态变量等
-
JDK8后由元空间(Metaspace)实现,使用本地内存
-
可能出现OutOfMemoryError
-
-
运行时常量池(Runtime Constant Pool)
-
方法区的一部分,存放编译期生成的各种字面量和符号引用
-
HashMap与HashTable的区别
特性 | HashMap | HashTable |
---|---|---|
线程安全 | 非线程安全 | 线程安全(方法使用synchronized修饰) |
性能 | 更高 | 较低(因同步开销) |
null处理 | 允许一个null键和多个null值 | 不允许null键或null值 |
继承关系 | 继承AbstractMap | 继承Dictionary(已过时) |
迭代器 | 使用快速失败(fail-fast)迭代器 | 使用Enumerator迭代器 |
初始容量 | 默认16,扩容为2n | 默认11,扩容为2n+1 |
哈希计算 | 对key的hashCode()二次哈希 | 直接使用key的hashCode() |
版本 | JDK1.2引入 | JDK1.0就存在 |
补充说明:
-
在Java 5以后,通常推荐使用ConcurrentHashMap代替HashTable,因为它提供了更好的并发性能
-
HashMap在JDK8中引入了红黑树优化,当链表长度超过8时会转为红黑树结构