I'm trying to convert documents(.docx/.xlsx/.pptx) to PDF using JOD Converter. I'm using OpenOffice 4.1.2 on Centos 7. My problem is, I'm getting constant CPU usage of 100% while i'm converting the file, and this is impacting the performance of overall machine. I have tried every possible option in the command line options, but ,unfortunately, haven't been able to mitigate this issue. I have searched on a lot of forums, and found that lot of other people are also facing the same problem, however, there is no solution out there. Through my readings, I realize this could be because memory leak problems in OpenOffice. Can someone please help me resolve or at-least mitigate this?
Below is the command that I use to spawn the OpenOffice instance.
/opt/openoffice4/program/soffice.bin -accept=socket,host=127.0.0.1,port=8016;urp; -env:UserInstallation=file:///tmp/.jodconverter_socket_host-127.0.0.1_port-8016 -headless -nocrashreport -nodefault -nofirststartwizard -nolockcheck -nologo -norestore
The code I'm using to convert the files is as follows:
package org.samples.docxconverters.jodconverter.pdf;
import java.io.File;
import org.apache.commons.io.FilenameUtils;
import org.artofsolving.jodconverter.OfficeDocumentConverter;
import org.artofsolving.jodconverter.office.DefaultOfficeManagerConfiguration;
import org.artofsolving.jodconverter.office.OfficeManager;
public class Word2PdfJod {
public static void main(String[] args) {
// 1) Start LibreOffice in headless mode.
OfficeManager officeManager = null;
try {
officeManager = new DefaultOfficeManagerConfiguration()
.setOfficeHome(new File("/Applications/OpenOffice.app/Contents/")).buildOfficeManager();
officeManager.start();
// 2) Create JODConverter converter
OfficeDocumentConverter converter = new OfficeDocumentConverter(
officeManager);
// 3) Create PDF
createPDF(converter);
} finally {
// 4) Stop OpenOffice in headless mode.
if (officeManager != null) {
officeManager.stop();
}
}
}
private static void createPDF(OfficeDocumentConverter converter) {
try {
long start = System.currentTimeMillis();
String src_file = "/Users/Aman/Documents/WindowsData/DocumentConversionPoc/Powerpoint2Pdf/JODConverterV3/Sample_pptx_files/AdeemSample2.pptx";
System.out.println(src_file.substring(0, src_file.lastIndexOf(".")) + "_" + FilenameUtils.getExtension(src_file) );
//Actual Conversion
converter.convert( new File(src_file), new File( src_file.substring(0, src_file.lastIndexOf(".")) + "_"
+ FilenameUtils.getExtension(src_file) +"_Jod.pdf") );
System.out.println("Time Taken in conversion - "+ (System.currentTimeMillis() - start) + "ms");
} catch (Throwable e) {
e.printStackTrace();
}
}
}
And the relevant jars can be downloaded from :
https://drive.google.com/file/d/0B4hS5IGxGOh9OE5Ca0RlbTdVclU/view?usp=sharing
If CPU is idle, a process will take 100% CPU time by default. It's normal. If this is causing hinderance in executing other processes (highly unlikely), you can set up priorities using nice.
nice <your command>
Or, you can install cpulimit, which makes your program sleep if it reaches a predefined CPU usage. Read about it here.
By reducing the number of cores your application can use, you can prevent the system from being locked:
Process.GetCurrentProcess().ProcessorAffinity = (System.IntPtr)2;
To set the affinity of CPUs using C#
Related
I'm seeing an apparent memory leak with a dotnet core 3.1 application in our Linux (Ubuntu 20.04) environment, but not our Windows (2012 R2) environment. I have run the same operations between the two, and it's clear that Linux is hanging onto memory (gigs worth) and Windows is properly disposing of it.
I've tried looking at dotnet core settings, (workstation vs server garbage collection, etc) and the defaults seem to be appropriate. I have tried researching the issue and have found a number of seemingly related posts here and elsewhere, but nothing conclusive or anything that has been helpful. Here are the most relevant posts I found:
Dotnet Core Docker Container Leaks RAM on Linux and causes OOM
How do I use server garbage collection with dotnet fsi?
https://github.com/dotnet/diagnostics/issues/1402
I have also tried more general memory troubleshooting using MS's official documentation and the dotnet-counters tool. "Working set" memory appeared to be what is getting bloated, the GC Heap didn't expand much and relinquished what it did find.
In code, what's happening is I am creating images using System.Drawing, the images are wrapped in "using" blocks, and I am calling dispose on those images when done.
Code example - in summary, this function takes a user's imported image, and scales them down to a more optimized size. The helper functions "scaleImage" & "imageToByteArray" are the items in question
UserImage[] userImages = this._repository.getImagesForUsersByIds(userIds.ToArray(), idList.ToArray());
List<UserImage> returnImages = new List<UserImage>();
foreach (UserImage img in userImages) {
try {
string filePath = this._fileManager.getFilePathOfEditorImage(img.OwnerId, img.Id, "." + img.ImageType);
if (!string.IsNullOrEmpty(filePath) && this._fileInfoHelper.doesFileExist(filePath)) {
System.Drawing.Image scaledImage;
if (size > 0) {
scaledImage = this._fileInfoHelper.scaleImage(filePath, size * size);
} else {
scaledImage = System.Drawing.Image.FromFile(filePath);
}
byte[] bytes = this._fileInfoHelper.imageToByteArray(scaledImage, this._fileInfoHelper.getFormatFromExtension(img.ImageType));
string type = this._fileInfoHelper.getContentType(filePath);
img.Base64 = "data:" + type.ToLower() + ";base64," + Convert.ToBase64String(bytes);
returnImages.Add(img);
scaledImage.Dispose();
}
}
catch (Exception ex) {
//could not convert image....
}
}
return Ok(returnImages.ToArray());
Code example for an image scaling function I'm using:
public Image scaleImage(string fileName, int scaleImageArea) {
Image returnVal = null;
using (var bmpTemp = new Bitmap(fileName)) {
using (Image sourceImage = new Bitmap(bmpTemp)) {
if (sourceImage.Width * sourceImage.Height > scaleImageArea) {
//We need to scale the image down.
float width, height;
//This is the targetArea that we are shooting for.
float ratio = (float)sourceImage.Width / (float)sourceImage.Height;
//The expression to get the width is width^2 * ratio = target
height = (float)Math.Sqrt(scaleImageArea / ratio);
width = height * ratio;
returnVal = new Bitmap(sourceImage, new Size((int)width, (int)height));
} else {
returnVal = new Bitmap(sourceImage);
}
bmpTemp.Dispose();
sourceImage.Dispose();
}
}
return returnVal;
}
Code example of image to byte array function:
public byte[] imageToByteArray(System.Drawing.Image imageIn, System.Drawing.Imaging.ImageFormat format) {
byte[] returnValue;
using (var ms = new MemoryStream()) {
imageIn.Save(ms, format);
imageIn.Dispose();
returnValue = ms.ToArray();
}
return returnValue;
}
Specific problem:
I have a memory leak in a Linux environment but not in windows with the same code. I suspect a dotnet core or other Linux-specific configuration/environment issue, but troubleshooting with official dotnet core memory leak tools has been a dead end.
Desired behavior:
I don't want the memory leak and would expect to see behavior in Linux similar to that of Windows.
My app uses some short sounds for user feedback. I use the following code:
private void playSound(String fileName) {
try {
FileSystemStorage fss = FileSystemStorage.getInstance();
String sep = fss.getFileSystemSeparator() + "";
String soundDir; // sounds must be in a directory
if (fss.getAppHomePath().endsWith(sep)) {
soundDir = fss.getAppHomePath() + "sounds"; // device
} else {
soundDir = fss.getAppHomePath() + sep + "sounds"; // simulator/windows
}
if (!fss.exists(soundDir)) {
// first time a sound is played: create directory
fss.mkdir(soundDir);
}
String filePath = soundDir + sep + fileName;
if (!fss.exists(filePath)) {
// first time this sound is played: copy from resources (place file in <project>/src)
InputStream is = Display.getInstance().getResourceAsStream(getClass(), "/" + fileName);
OutputStream os = fss.openOutputStream(filePath);
com.codename1.io.Util.copy(is, os);
}
Media media = MediaManager.createMedia(filePath, false);
//media.setVolume(100);
media.play();
} catch (IOException ex) {
log("Error playing " + fileName + " " + ex.getMessage());
}
}
Example call:
playSound("error.mp3");
This works fine on devices and in the simulator. However, if I do a long automatic test in the simulator (using Windows), playing a sound about every second,
this eats up all the RAM until Windows crashes. The Windows task manager, however, shows no exceptional memory usage of NetBeans and the Java process.
So my questions are: Is my code correct? Can this happen on devices too? Or else is there a way to prevent this in the simulator/Windows?
P.S.
I also tried the code from How to bundle sounds with Codename One?. That has the same problem and also
some sounds get lost (are not played).
I also tried the simple code from Codename One - Play a sound but that doesn't work.
We generally recommend keeping the Media instance for this sort of use case.
But if you can't just make sure to call cleanup when you're done:
MediaManager.addCompletionHandler(media, () -> media.cleanup());
media.play();
I am working on a small tool to schedule p4 sync daily at specific times.
In this tool, I want to display the outputs from the P4API while it is running commands.
I can see that the P4API.net has a P4Callbacks class, with several delegates: InfoResultsDelegate, TaggedOutputDelegate, LogMessageDelegate, ErrorDelegate.
My question is: How can I use those, I could not find a single example online of that. A short example code would be amazing !
Note: I am quite a beginner and have never used delegates before.
Answering my own questions by an example. I ended up figuring out by myself, it is a simple event.
Note that this only works with P4Server. My last attempt at getting TaggedOutput from a P4.Connection was unsuccessful, they were never triggered when running a command.
So, here is a code example:
P4Server p4Server = new P4Server(syncPath);
p4Server.TaggedOutputReceived += P4ServerTaggedOutputEvent;
p4Server.ErrorReceived += P4ServerErrorReceived;
bool syncSuccess = false;
try
{
P4Command syncCommand = new P4Command(p4Server, "sync", true, syncPath + "\\...");
P4CommandResult rslt = syncCommand.Run();
syncSuccess=true;
//Here you can read the content of the P4CommandResult
//But it will only be accessible when the command is finished.
}
catch (P4Exception ex) //Will be caught only when the command has completely failed
{
Console.WriteLine("P4Command failed: " + ex.Message);
}
And the two methods, those will be triggered while the sync command is being executed.
private void P4ServerErrorReceived(uint cmdId, int severity, int errorNumber, string data)
{
Console.WriteLine("P4ServerErrorReceived:" + data);
}
private void P4ServerTaggedOutputEvent(uint cmdId, int ObjId, TaggedObject Obj)
{
Console.WriteLine("P4ServerTaggedOutputEvent:" + Obj["clientFile"]);
}
i have a problem to run configure.init() in my Jetty-container (run-jetty-run in Eclipse with Springframework )
After reaching configure.init() the client-service blocks without any notice or exception.
If i run the same code in a console-java program it works.
I would expect output:
Enter init()
OK init()
Server-Version:2.6.1
Does somebody has any idea or experience with it ?
Java-Driver-version is 2.5.7.
Codesnippet:
public void arangoVersion() {
try {
configure = new ArangoConfigure();
write("Enter init()");
configure.init();
write("OK init()"); // never reached :(
arangoDriver = new ArangoDriver(configure);
write("Server-Version:" + arangoDriver.getVersion().getVersion());
} catch (ArangoException ax) {
write("Arango-Exception" + ax.getErrorMessage() + " , Nr. : "
+ ax.getCode());
} catch (Exception ex) {
write("Exception" + ex.getMessage() );
}
}
public void write( String text ) {
System.out.println( text );
// for web: logger.debug( text );
}
Thanks in advance
SOLVED
Are there different versions of httpclient.jar in your maven
dependencies? The java driver uses httpclient 4.3.6 which is not
compatible with older versions. – fceller Aug 28 at 8:20
Yes, indeed there was the mentioned version conflict with httpclient. An older httpclient-version was in an included (Eclipse-)project.
So configure.init() is working now.
(I would propose to catch the no-class-found-exception explitely in the Arango-Java-Driver and to make a version-check and output for httpclient. httpclient is widely spread.)
After updating the httpclient and resolving some small incompatibilities with my application the second problem occurs:
Now the ArangoDriver ran into the void with no visible reaction in my spring-application.
A debugging-session revealed that the actions of ArangoDriver where encapsulated in Springframework-transactions due AOP-coverage for all Spring-services and throws a NoClassFound-exception for the ArangoDriver.
After moving the Arango-java-driver in the same Maven-POM-layer as the SpringTX it was running perfectly.
Thanks to all.
My app is making heavy use of webservice calls. Lately, some of the calls got stuck. After playing around I figured out that it
happens mostly for release builds
happens in the Simulator AND on the device (iPad, iOS 4.3)
happens more often on iPad 1 than on iPad 2
it is not limited to web services an SOAP but also affects the System.Net.WebClient
does not affest [NSString stringWithContentsOfUrl:] if invoked manually, since not bound
The effect is that the CPU load of the device drops to zero. memory is stable (in my demo project 8.5MB). If I put Console.WriteLines() everywhere, I can see that the code is stuck inside one of the WebClient.Download*() methods.
The code below demonstrates that (if built RELEASE with MT 4.0.1, LLVM off or on does not matter) downloading a file from the web over and over again fails sometimes right away on the first try, sometimes after 10 times, sometimes after around 30 downloads.
It is totally random. If you think it works, kill the app and restart it and eventually it will hang.
When building the same using MT 3.2.6, the downloading goes on all day without issues. It is impossible to break it.
MONO installed is the latest available version.
Can somebody from the MT team comment on it?
using System;
using System.IO;
using System.Threading;
using System.Net;
using System.Collections.Generic;
using System.Linq;
using MonoTouch.Foundation;
using MonoTouch.UIKit;
namespace iOSTest
{
public class Application
{
static void Main (string[] args)
{
UIApplication.Main (args);
}
}
// The name AppDelegate is referenced in the MainWindow.xib file.
public partial class AppDelegate : UIApplicationDelegate
{
private Thread oThread;
// This method is invoked when the application has loaded its UI and its ready to run
public override bool FinishedLaunching (UIApplication app, NSDictionary options)
{
// Make a release build and run on iPad 1 with iOS 4.3.2.
// Fails after downloading between 1 time and 30 times on MT 4.0.1.
// It is possible that it seems to work. Then just kill the app and restart and suddenly the effect
// will become visible. If you watch it with Instruments, CPU suddenly drops to zero. The app then is
// stuck somewhere inside WebClient. After about 10 minutes, an exception will be thrown (timeout).
// Never fails on MT 3.2.6
Console.WriteLine(MonoTouch.Constants.Version);
// A label that counts how often we downloaded.
UILabel oLbl = new UILabel(new System.Drawing.RectangleF(40, 100, 150, 30));
window.AddSubview(oLbl);
// This thread downloads the same file over and over again.
// The thread is not required to demonstrate the issue. The same problem occurs
// if the download is running on the main thread.
this.oThread = new Thread(delegate()
{
using(var oPool = new NSAutoreleasePool())
{
int i = 0;
while(true)
{
// Setup webclient and download a file from my website (around 2.4 MB)
WebClient oClient = new WebClient();
// It would be nice to hange it to your own URL to save me from all the traffic.
oClient.DownloadFile(new Uri("http://www.wildsau.net/image.axd?picture=2011%2f4%2fDSC05178.JPG"), Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), "test.jpg"));
// Increase counter and update label.
i++;
this.InvokeOnMainThread(delegate { oLbl.Text = i.ToString(); });
Console.WriteLine("Done " + i + " times.");
}
}
});
// Have a button that starts the action.
UIButton oBtn = UIButton.FromType(UIButtonType.RoundedRect);
oBtn.SetTitle("Download", UIControlState.Normal);
oBtn.Frame = new System.Drawing.RectangleF(40, 40, 150, 30);
oBtn.TouchUpInside += delegate(object sender, System.EventArgs e)
{
this.oThread.Start();
};
window.AddSubview(oBtn);
window.MakeKeyAndVisible ();
return true;
}
// This method is required in iPhoneOS 3.0
public override void OnActivated (UIApplication application)
{
}
}
}
From Gonzalo-
When the problem occurs, "kicking" the threadpool by adding another
work item will make the problem go away.
Something like this (not tested or compiled ;-) should do:
Timer timer = new Timer (AddMe);
...
WebClient wc = new WebClient ();
Uri uri = new Uri(url);
timer.Change (0, 500); // Trigger it now and every 500ms
byte[] bytes = wc.DownloadData(uri);
timer.Change (Timeout.Infinite, Timeout.Infinite);
....
static void AddMe (object state)
{
// Empty.
}
#
Works 100% of the time - for me at least - YMMV. And it did, once we put the code under stress (Lots of files to download) it stalled again. Just heard from MT that 4.0.6 will have the fix in it. Should see it later this week!
Promised to be fixed by Xamarin in the next major release. Still does not work in 4.0.4 though.