当前位置:  开发笔记 > 编程语言 > 正文

JVM堆栈大小规范

如何解决《JVM堆栈大小规范》经验,为你挑选了1个好方法。

我有一个常规的64位热点JVM,其堆栈大小为1 MB.现在我试图序列化一个具有3022个父级的层次结构的对象,这给了我SO(反讽)异常.

这是一些代码:

while(epc.getParent()!=null){

      epc=epc.getParent();
      count++;
     }
     print(count);//3022

上面的代码只是告诉层次结构,但当我尝试将epc对象序列化到ObjectOutputStream 时,会发生实际问题.

问题,JVM中1 MB堆栈大小的状态是什么,因为我不知道堆栈帧的大小是多少?我确定每个堆栈帧不是1KB,因为我在-Xss3000k成功运行了代码.

还有一个问题,如果我放置-Xss3000k的JVM选项,每个线程的堆栈大小是否为3000k?



1> Stephen C..:

问题,JVM中1 MB堆栈大小的状态是什么,因为我不知道堆栈帧的大小是多少?

1 MB默认线程堆栈大小意味着每个线程默认具有1MB(1048576字节)的堆栈空间.例外情况是,如果您的代码使用其中一个Thread构造函数创建一个线程,您可以在其中提供堆栈大小参数.

堆栈帧的大小取决于被调用的方法.它需要保存方法的参数和局部变量,因此帧大小取决于它们的大小.每个帧还需要(我认为)两个额外的单词来保存已保存的帧指针和保存的返回地址.

请注意,在递归算法中,您可以为一个"递归级别"拥有多个堆栈帧.对于writeObject(在Java 8中),使用的算法是递归的,并且每个级别的数据结构通常有4个帧被序列化:

writeObject0 
writeOrdinaryObject
writeSerialData
defaultWriteFields
writeObject0
etcetera

由于编译器的差异以及ObjectInputStream/ObjectOutputStream的实现的变化,实际的帧大小将取决于平台.您最好尝试(粗略地)测量所需的堆栈空间,而不是尝试从第一原理预测帧大小.

还有一个问题,如果我放置-Xss3000k的JVM选项,每个线程的堆栈大小是否为3000k?

是的......除了我上面描述的例外.

解决您的困境的一个可能的解决方案是创建一个特殊的线程,其中包含一个用于序列化的大堆栈.反序列化将需要具有大堆栈的类似线程.对于其余的线程,默认的堆栈大小应该没问题.

其他可能的方案:

实现writeReplacereadResolve方法将epc对象的父结构展平为一个数组,这样就不会得到深度递归.(显然,需要非递归地完成展平/不展平.)

你打电话之前做同样的扁平化writeObject等等.

使用不同的序列化机制,或者可能是自定义机制.

推荐阅读
wurtjq
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有