在我們的一個項目中,用戶可以將文件附加到他的帳戶。我們將這些文件存儲在MS-SQL數據庫中。因此,我們有如下一段代碼:EntityManager內存消耗
@Entity
public class File extends AbstractEntity {
@Lob
@Basic
private byte[] data;
@Nullable
public byte[] getData() {
return data;
}
public void setData(byte[] data) {
this.data = data;
}
public File() {
}
public File(byte[] data) {
this.data = data;
}
}
public class SomeBean {
@PersistenceContext
protected EntityManager em;
public Long uploadFile(@NotNull byte[] data) {
final PhysicalFile physicalFile = new PhysicalFile();
physicalFile.setData(data);
em.persist(physicalFile);
return physicalFile.getId();
}
}
,一切都不錯,漂亮,之前我們嘗試上傳40 MB的文件,並得到了java.lang.RuntimeException: javax.transaction.RollbackException: [com.arjuna.ats.internal.jta.transaction.arjunacore.commitwhenaborted] [com.arjuna.ats.internal.jta.transaction.arjunacore.commitwhenaborted] Can't commit because the transaction is in aborted state
,這是在uploadFile()
方法內外因java.lang.OutOfMemoryError: Java heap space
。
我做了一個堆轉儲,並在VisualVM中查看它。
400多MB的char[]
和100 + MB的byte[]
。在開始,我們的應用程序(包括JBoss
)正在使用大約60-65 MB的堆。所以,問題是,爲什麼EntityManager
像瘋了一樣消耗堆內存?