[JBoss JIRA] (JBREM-1324) Always hit OutOfMemoryError If I try to invoke ejb method with large object as its parameter at the marshlling step
by licheng cheng (JIRA)
[ https://issues.jboss.org/browse/JBREM-1324?page=com.atlassian.jira.plugin... ]
licheng cheng updated JBREM-1324:
---------------------------------
Attachment: SerializableInputStream.java
> Always hit OutOfMemoryError If I try to invoke ejb method with large object as its parameter at the marshlling step
> -------------------------------------------------------------------------------------------------------------------
>
> Key: JBREM-1324
> URL: https://issues.jboss.org/browse/JBREM-1324
> Project: JBoss Remoting
> Issue Type: Bug
> Security Level: Public(Everyone can see)
> Components: marshall
> Affects Versions: 2.2.2.SP10
> Environment: WindowsXP + jdk1.6
> Reporter: licheng cheng
> Fix For: 2.2.2.SP10
>
> Attachments: SerializableInputStream.java
>
>
> In our stateless EJB, there is one API defined as below.
> public void modelSave(SerializableInputStream model) throws java.rmi.RemoteException;
> The SerializableInputStream is defined as below and its whole definition is attached. The intent of defining such class is that sometimes we need to pass through large object (its content may be more than 300M) as parameter to remote ejb, while the -Xmx of the JVM is only 512M by default. With such serializable inputstream, expect JBoss not to load the whole object into JVM before invoking ejb method to avoid the OutOfMemoryError issue.
> public class SerializableInputStream extends InputStream implements Serializable {
> private InputStream stream;
> ....
> //---------------------------< Serializable >-------------------------------
> private void writeObject(ObjectOutputStream out)
> throws IOException {
> byte[] buffer = new byte[4096];
> int bytes;
> while ((bytes = stream.read(buffer)) >= 0) {
> // Write a segment of the input stream
> if (bytes > 0) {
> // just to ensure that no 0 is written
> out.writeInt(bytes);
> out.write(buffer, 0, bytes);
> }
> }
> // Write the end of stream marker
> out.writeInt(0);
> // close stream
> stream.close();
> }
> private void readObject(ObjectInputStream in)
> throws IOException {
> final File file = File.createTempFile("serializable-stream", "bin");
> OutputStream out = new FileOutputStream(file);
> byte[] buffer = new byte[4096];
> for (int bytes = in.readInt(); bytes > 0; bytes = in.readInt()) {
> if (buffer.length < bytes) {
> buffer = new byte[bytes];
> }
> in.readFully(buffer, 0, bytes);
> out.write(buffer, 0, bytes);
> }
> out.close();
> stream = new FileInputStream(file) {
> private boolean closed = false;
> public void close() throws IOException {
> super.close();
> closed = true;
> file.delete();
> }
> ...
> };
> }
> }
> But from the test result, I can that JBoss marshaller first read its content (the serializable inputstream) into a byte array, which means the big object is loaded into memory. With our default JVM setting, we always hit OOM issue as below
> 2013-08-07 14:30:21,001 ERROR [STDERR] Caused by: java.lang.Exception: java.lang.OutOfMemoryError: Java heap space
> 2013-08-07 14:30:21,001 ERROR [STDERR] at org.jboss.invocation.unified.interfaces.UnifiedInvokerProxy.invoke(UnifiedInvokerProxy.java:222)
> 2013-08-07 14:30:21,001 ERROR [STDERR] at org.jboss.invocation.InvokerInterceptor.invokeInvoker(InvokerInterceptor.java:365)
> 2013-08-07 14:30:21,016 ERROR [STDERR] at org.jboss.invocation.InvokerInterceptor.invoke(InvokerInterceptor.java:197)
> 2013-08-07 14:30:21,016 ERROR [STDERR] at org.jboss.proxy.TransactionInterceptor.invoke(TransactionInterceptor.java:61)
> 2013-08-07 14:30:21,016 ERROR [STDERR] at org.jboss.proxy.SecurityInterceptor.invoke(SecurityInterceptor.java:70)
> 2013-08-07 14:30:21,016 ERROR [STDERR] at org.jboss.proxy.ejb.StatelessSessionInterceptor.invoke(StatelessSessionInterceptor.java:112)
> 2013-08-07 14:30:21,016 ERROR [STDERR] at org.jboss.proxy.ClientContainer.invoke(ClientContainer.java:100)
> 2013-08-07 14:30:21,016 ERROR [STDERR] ... 39 more
> 2013-08-07 14:30:21,016 ERROR [STDERR] Caused by: java.lang.OutOfMemoryError: Java heap space
> 2013-08-07 14:30:21,016 ERROR [STDERR] at java.util.Arrays.copyOf(Arrays.java:2786)
> 2013-08-07 14:30:21,016 ERROR [STDERR] at java.io.ByteArrayOutputStream.toByteArray(ByteArrayOutputStream.java:133)
> 2013-08-07 14:30:21,016 ERROR [STDERR] at org.jboss.invocation.MarshalledValue.<init>(MarshalledValue.java:72)
> 2013-08-07 14:30:21,016 ERROR [STDERR] at org.jboss.invocation.MarshalledValueEX.<init>(MarshalledValueEX.java:47)
> 2013-08-07 14:30:21,016 ERROR [STDERR] at org.jboss.invocation.unified.interfaces.JavaSerializationManager.createdMarshalledValue(JavaSerializationManager.java:105)
> 2013-08-07 14:30:21,016 ERROR [STDERR] at org.jboss.invocation.MarshalledInvocation.createMarshalledValue(MarshalledInvocation.java:628)
> 2013-08-07 14:30:21,016 ERROR [STDERR] at org.jboss.invocation.MarshalledInvocation.writeExternal(MarshalledInvocation.java:570)
> 2013-08-07 14:30:21,016 ERROR [STDERR] at java.io.ObjectOutputStream.writeExternalData(ObjectOutputStream.java:1429)
> 2013-08-07 14:30:21,016 ERROR [STDERR] at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1398)
> 2013-08-07 14:30:21,016 ERROR [STDERR] at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1158)
> 2013-08-07 14:30:21,016 ERROR [STDERR] at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1518)
> 2013-08-07 14:30:21,016 ERROR [STDERR] at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1483)
> 2013-08-07 14:30:21,016 ERROR [STDERR] at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1400)
> 2013-08-07 14:30:21,016 ERROR [STDERR] at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1158)
> 2013-08-07 14:30:21,016 ERROR [STDERR] at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:330)
> 2013-08-07 14:30:21,016 ERROR [STDERR] at org.jboss.remoting.serialization.impl.java.JavaSerializationManager.sendObjectVersion2_2(JavaSerializationManager.java:119)
> 2013-08-07 14:30:21,016 ERROR [STDERR] at org.jboss.remoting.serialization.impl.java.JavaSerializationManager.sendObject(JavaSerializationManager.java:94)
> 2013-08-07 14:30:21,016 ERROR [STDERR] at org.jboss.remoting.marshal.serializable.SerializableMarshaller.write(SerializableMarshaller.java:120)
> 2013-08-07 14:30:21,016 ERROR [STDERR] at org.jboss.invocation.unified.marshall.InvocationMarshaller.write(InvocationMarshaller.java:75)
> 2013-08-07 14:30:21,016 ERROR [STDERR] at org.jboss.remoting.transport.socket.MicroSocketClientInvoker.versionedWrite(MicroSocketClientInvoker.java:969)
> 2013-08-07 14:30:21,016 ERROR [STDERR] at org.jboss.remoting.transport.socket.MicroSocketClientInvoker.transport(MicroSocketClientInvoker.java:606)
> 2013-08-07 14:30:21,016 ERROR [STDERR] at org.jboss.remoting.MicroRemoteClientInvoker.invoke(MicroRemoteClientInvoker.java:122)
> 2013-08-07 14:30:21,016 ERROR [STDERR] at org.jboss.remoting.Client.invoke(Client.java:1634)
> 2013-08-07 14:30:21,016 ERROR [STDERR] at org.jboss.remoting.Client.invoke(Client.java:548)
> Although passing big object with Remote ejb call is not a common use case, but I think it will be better if JBoss could consider such case.
--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira
11 years, 1 month
[JBoss JIRA] (JBREM-1324) Always hit OutOfMemoryError If I try to invoke ejb method with large object as its parameter at the marshlling step
by licheng cheng (JIRA)
licheng cheng created JBREM-1324:
------------------------------------
Summary: Always hit OutOfMemoryError If I try to invoke ejb method with large object as its parameter at the marshlling step
Key: JBREM-1324
URL: https://issues.jboss.org/browse/JBREM-1324
Project: JBoss Remoting
Issue Type: Bug
Security Level: Public (Everyone can see)
Components: marshall
Affects Versions: 2.2.2.SP10
Environment: WindowsXP + jdk1.6
Reporter: licheng cheng
Fix For: 2.2.2.SP10
In our stateless EJB, there is one API defined as below.
public void modelSave(SerializableInputStream model) throws java.rmi.RemoteException;
The SerializableInputStream is defined as below and its whole definition is attached. The intent of defining such class is that sometimes we need to pass through large object (its content may be more than 300M) as parameter to remote ejb, while the -Xmx of the JVM is only 512M by default. With such serializable inputstream, expect JBoss not to load the whole object into JVM before invoking ejb method to avoid the OutOfMemoryError issue.
public class SerializableInputStream extends InputStream implements Serializable {
private InputStream stream;
....
//---------------------------< Serializable >-------------------------------
private void writeObject(ObjectOutputStream out)
throws IOException {
byte[] buffer = new byte[4096];
int bytes;
while ((bytes = stream.read(buffer)) >= 0) {
// Write a segment of the input stream
if (bytes > 0) {
// just to ensure that no 0 is written
out.writeInt(bytes);
out.write(buffer, 0, bytes);
}
}
// Write the end of stream marker
out.writeInt(0);
// close stream
stream.close();
}
private void readObject(ObjectInputStream in)
throws IOException {
final File file = File.createTempFile("serializable-stream", "bin");
OutputStream out = new FileOutputStream(file);
byte[] buffer = new byte[4096];
for (int bytes = in.readInt(); bytes > 0; bytes = in.readInt()) {
if (buffer.length < bytes) {
buffer = new byte[bytes];
}
in.readFully(buffer, 0, bytes);
out.write(buffer, 0, bytes);
}
out.close();
stream = new FileInputStream(file) {
private boolean closed = false;
public void close() throws IOException {
super.close();
closed = true;
file.delete();
}
...
};
}
}
But from the test result, I can that JBoss marshaller first read its content (the serializable inputstream) into a byte array, which means the big object is loaded into memory. With our default JVM setting, we always hit OOM issue as below
2013-08-07 14:30:21,001 ERROR [STDERR] Caused by: java.lang.Exception: java.lang.OutOfMemoryError: Java heap space
2013-08-07 14:30:21,001 ERROR [STDERR] at org.jboss.invocation.unified.interfaces.UnifiedInvokerProxy.invoke(UnifiedInvokerProxy.java:222)
2013-08-07 14:30:21,001 ERROR [STDERR] at org.jboss.invocation.InvokerInterceptor.invokeInvoker(InvokerInterceptor.java:365)
2013-08-07 14:30:21,016 ERROR [STDERR] at org.jboss.invocation.InvokerInterceptor.invoke(InvokerInterceptor.java:197)
2013-08-07 14:30:21,016 ERROR [STDERR] at org.jboss.proxy.TransactionInterceptor.invoke(TransactionInterceptor.java:61)
2013-08-07 14:30:21,016 ERROR [STDERR] at org.jboss.proxy.SecurityInterceptor.invoke(SecurityInterceptor.java:70)
2013-08-07 14:30:21,016 ERROR [STDERR] at org.jboss.proxy.ejb.StatelessSessionInterceptor.invoke(StatelessSessionInterceptor.java:112)
2013-08-07 14:30:21,016 ERROR [STDERR] at org.jboss.proxy.ClientContainer.invoke(ClientContainer.java:100)
2013-08-07 14:30:21,016 ERROR [STDERR] ... 39 more
2013-08-07 14:30:21,016 ERROR [STDERR] Caused by: java.lang.OutOfMemoryError: Java heap space
2013-08-07 14:30:21,016 ERROR [STDERR] at java.util.Arrays.copyOf(Arrays.java:2786)
2013-08-07 14:30:21,016 ERROR [STDERR] at java.io.ByteArrayOutputStream.toByteArray(ByteArrayOutputStream.java:133)
2013-08-07 14:30:21,016 ERROR [STDERR] at org.jboss.invocation.MarshalledValue.<init>(MarshalledValue.java:72)
2013-08-07 14:30:21,016 ERROR [STDERR] at org.jboss.invocation.MarshalledValueEX.<init>(MarshalledValueEX.java:47)
2013-08-07 14:30:21,016 ERROR [STDERR] at org.jboss.invocation.unified.interfaces.JavaSerializationManager.createdMarshalledValue(JavaSerializationManager.java:105)
2013-08-07 14:30:21,016 ERROR [STDERR] at org.jboss.invocation.MarshalledInvocation.createMarshalledValue(MarshalledInvocation.java:628)
2013-08-07 14:30:21,016 ERROR [STDERR] at org.jboss.invocation.MarshalledInvocation.writeExternal(MarshalledInvocation.java:570)
2013-08-07 14:30:21,016 ERROR [STDERR] at java.io.ObjectOutputStream.writeExternalData(ObjectOutputStream.java:1429)
2013-08-07 14:30:21,016 ERROR [STDERR] at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1398)
2013-08-07 14:30:21,016 ERROR [STDERR] at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1158)
2013-08-07 14:30:21,016 ERROR [STDERR] at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1518)
2013-08-07 14:30:21,016 ERROR [STDERR] at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1483)
2013-08-07 14:30:21,016 ERROR [STDERR] at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1400)
2013-08-07 14:30:21,016 ERROR [STDERR] at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1158)
2013-08-07 14:30:21,016 ERROR [STDERR] at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:330)
2013-08-07 14:30:21,016 ERROR [STDERR] at org.jboss.remoting.serialization.impl.java.JavaSerializationManager.sendObjectVersion2_2(JavaSerializationManager.java:119)
2013-08-07 14:30:21,016 ERROR [STDERR] at org.jboss.remoting.serialization.impl.java.JavaSerializationManager.sendObject(JavaSerializationManager.java:94)
2013-08-07 14:30:21,016 ERROR [STDERR] at org.jboss.remoting.marshal.serializable.SerializableMarshaller.write(SerializableMarshaller.java:120)
2013-08-07 14:30:21,016 ERROR [STDERR] at org.jboss.invocation.unified.marshall.InvocationMarshaller.write(InvocationMarshaller.java:75)
2013-08-07 14:30:21,016 ERROR [STDERR] at org.jboss.remoting.transport.socket.MicroSocketClientInvoker.versionedWrite(MicroSocketClientInvoker.java:969)
2013-08-07 14:30:21,016 ERROR [STDERR] at org.jboss.remoting.transport.socket.MicroSocketClientInvoker.transport(MicroSocketClientInvoker.java:606)
2013-08-07 14:30:21,016 ERROR [STDERR] at org.jboss.remoting.MicroRemoteClientInvoker.invoke(MicroRemoteClientInvoker.java:122)
2013-08-07 14:30:21,016 ERROR [STDERR] at org.jboss.remoting.Client.invoke(Client.java:1634)
2013-08-07 14:30:21,016 ERROR [STDERR] at org.jboss.remoting.Client.invoke(Client.java:548)
Although passing big object with Remote ejb call is not a common use case, but I think it will be better if JBoss could consider such case.
--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira
11 years, 1 month