RMI 线程由于 java.lang.OutOfMemoryError: Java 堆空间而终止

发布于 2024-07-13 01:00:45 字数 2133 浏览 6 评论 0原文

我正在开发一个基于comp的应用程序。 在此应用程序中,有 n 个容器,它们通过彼此提供的 RMI 服务相互通信。 在某一时刻,连接到我的容器的一个 RMI 线程由于内存不足错误而丢失了连接,但连接到我的容器的所有其他 RMI 线程都工作正常。

错误的堆栈跟踪如下:

Exception dispatching call to [655d565c:11f1d5dbae2:-7ffb, -3259564578052694518] in thread "RMI TCP Connection(21)-132.186.96.179" at Wed Jan 28 18:50:37 GMT+05:30 2009: 
java.lang.OutOfMemoryError: Java heap space
    at java.lang.reflect.Array.newArray(Native Method)
    at java.lang.reflect.Array.newInstance(Unknown Source)
    at java.io.ObjectInputStream.readArray(Unknown Source)
    at java.io.ObjectInputStream.readObject0(Unknown Source)
    at java.io.ObjectInputStream.defaultReadFields(Unknown Source)
    at java.io.ObjectInputStream.readSerialData(Unknown Source)
    at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
    at java.io.ObjectInputStream.readObject0(Unknown Source)
    at java.io.ObjectInputStream.defaultReadFields(Unknown Source)
    at java.io.ObjectInputStream.readSerialData(Unknown Source)
    at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
    at java.io.ObjectInputStream.readObject0(Unknown Source)
    at java.io.ObjectInputStream.readObject(Unknown Source)
    at sun.rmi.server.UnicastRef.unmarshalValue(Unknown Source)
    at sun.rmi.server.UnicastServerRef.dispatch(Unknown Source)
    at sun.rmi.transport.Transport$1.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.Transport.serviceCall(Unknown Source)
    at sun.rmi.transport.tcp.TCPTransport.handleMessages(Unknown Source)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(Unknown Source)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)

要查看此异常,我必须激活 RMI 特定日志记录。 发生此问题的原因是此终止线程的每个 RMI 调用都会向我的容器堆添加一些数据。 并且在某些时候它的大小超出了。

我向你们提出的问题是,如果我的容器的堆大小内存不足,为什么其他线程正在工作? 如果您有任何想法,请告诉我。

I am working on a comp based application.
In this application, there are n number of containers that communicate to each other via RMI services they provide to each other.
At a certaion point, one rmi thread connected to my container is lost the connection due to out of memory error, but all other RMI thread connected to my container are working fine.

The stack tarce of the error is here :

Exception dispatching call to [655d565c:11f1d5dbae2:-7ffb, -3259564578052694518] in thread "RMI TCP Connection(21)-132.186.96.179" at Wed Jan 28 18:50:37 GMT+05:30 2009: 
java.lang.OutOfMemoryError: Java heap space
    at java.lang.reflect.Array.newArray(Native Method)
    at java.lang.reflect.Array.newInstance(Unknown Source)
    at java.io.ObjectInputStream.readArray(Unknown Source)
    at java.io.ObjectInputStream.readObject0(Unknown Source)
    at java.io.ObjectInputStream.defaultReadFields(Unknown Source)
    at java.io.ObjectInputStream.readSerialData(Unknown Source)
    at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
    at java.io.ObjectInputStream.readObject0(Unknown Source)
    at java.io.ObjectInputStream.defaultReadFields(Unknown Source)
    at java.io.ObjectInputStream.readSerialData(Unknown Source)
    at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
    at java.io.ObjectInputStream.readObject0(Unknown Source)
    at java.io.ObjectInputStream.readObject(Unknown Source)
    at sun.rmi.server.UnicastRef.unmarshalValue(Unknown Source)
    at sun.rmi.server.UnicastServerRef.dispatch(Unknown Source)
    at sun.rmi.transport.Transport$1.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.Transport.serviceCall(Unknown Source)
    at sun.rmi.transport.tcp.TCPTransport.handleMessages(Unknown Source)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(Unknown Source)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)

To view this exception, I had to activate RMI specific logging. This problem has occured because each RMI call of this terminated Thread adds some data to the heap of my container.
and at certain point its size excedes.

My question to you guys is that if it is out of memory in heap size of my container why other threads are working?
pls let me know if you have any idea.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

吃颗糖壮壮胆 2024-07-20 01:00:45

失败的调用是

java.lang.reflect.Array.newArray(Native Method),

这意味着失败的 RMI 线程正在尝试分配数组。 不幸的是,它没有告诉我们它试图分配有多大的数组。 如果它试图分配一个巨大数组,并且失败了,那么这不会伤害任何其他线程。 失败的请求是否有什么不同之处,它必须比正在发出的其他请求分配更多更多的内存?

详细说明一下……假设由于某种原因,这个请求试图分配一个 500 兆的数组(并且堆上没有足够的内存)。 好吧,分配请求将会失败。 但只要堆仍然有足够的内存来满足正常的分配请求,其他线程创建新对象就不会有问题。

The failed call is

java.lang.reflect.Array.newArray(Native Method)

which means that the failing RMI thread was trying to allocate an array. Unfortunately, it doesn't tell us how big an array it was trying to allocate. It it was trying to allocate a huge array, and failed, then this would not hurt any other thread. Is there anything different about the failing request that it would have to allocate much more memory than the other requests that are being made?

To elaborate ... let's say that for some reason this one request is trying to allocate a 500 meg array (and there isn't enough memory on the heap). Well, that allocation request will fail. But as long as the heap still has enough memory for normal allocation requests, the other threads won't have a problem creating new objects.

や三分注定 2024-07-20 01:00:45

简单的答案:因为其他操作没有失败操作的内存要求。

更长的答案从查看堆栈跟踪开始:

java.lang.OutOfMemoryError: Java heap space at java.lang.reflect.Array.newArray(Native Method) at
java.lang.reflect.Array.newInstance(Unknown Source) at java.io.ObjectInputStream.readArray(Unknown Source) at
java.io.ObjectInputStream.readObject0(Unknown Source) at java.io.ObjectInputStream.defaultReadFields(Unknown
...
sun.rmi.transport.tcp.TCPTransport.handleMessages(Unknown Source) at  

因此,失败的线程正在尝试创建一个新数组,以便处理传入的请求。 如果该数组特别大,则请求处理程序可能无法分配它,而使用较小数据量的其他请求将毫无问题地处理。

所以,第一个问题是:这个数组有多大? 您应该在客户端放置一些日志记录来确定这一点。 如果特定客户端尝试发送异常大的数组,您可能需要减小其大小。

第二个问题:您是否为服务器 JVM 提供了足够的内存来处理预期的负载? Jave 是少数仍然需要您告诉它程序需要多少内存的环境之一,并且默认值相当小(我相信是 64M)。 查看 -ms 和 -mx 参数以了解如何增加它。

Simple answer: because other operations don't have the memory requirements of the operation that fails.

Longer answer starts with looking at the stack trace:

java.lang.OutOfMemoryError: Java heap space at java.lang.reflect.Array.newArray(Native Method) at
java.lang.reflect.Array.newInstance(Unknown Source) at java.io.ObjectInputStream.readArray(Unknown Source) at
java.io.ObjectInputStream.readObject0(Unknown Source) at java.io.ObjectInputStream.defaultReadFields(Unknown
...
sun.rmi.transport.tcp.TCPTransport.handleMessages(Unknown Source) at  

So, the thread that's failing is trying to create a new array, in order to process an incoming request. If that array is particularly large, then the request handler may be unable to allocate it, while other requests that use smaller amounts of data will process without a problem.

So, the first question is: how big is that array? You should put some logging on the client side to determine this. And if a particular client is trying to send an exceptionally large array, you might need to reduce its size.

Second question: have you given the server JVM enough memory to handle the expected load? Jave is one of the few environments that still require you to tell it how much memory a program needs, and the default is quite small (64M I believe). Look into the -ms and -mx parameters to learn how to increase it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文