gpt4 book ai didi

java - JVM 堆栈大小规范

转载 作者:塔克拉玛干 更新时间:2023-11-01 21:32:38 26 4
gpt4 key购买 nike

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

这是一些代码:

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

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

上面的代码只是为了告诉层次结构,但当我尝试将 epc 对象序列化到 ObjectOutputStream 时,实际问题出现了。

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

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

最佳答案

Question, what does 1 MB stack size states in JVM as I have no idea what size a stack frame of?

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

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

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

writeObject0 
writeOrdinaryObject
writeSerialData
defaultWriteFields
writeObject0
etcetera

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

One more question, does every thread has 3000k stack size if I put a JVM option of -Xss3000k ?

是的......除了我在上面描述的异常(exception)情况。

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

其他可能的解决方案:

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

  • 在调用 writeObject 等之前, 执行相同的扁平化操作。

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

关于java - JVM 堆栈大小规范,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37026018/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com