android how to dynamically get memory usage of the app like showing with android studio profiler - android-memory

using the getRuntimeMemoryUsage() to get memory usage from Runtime.getRuntime()
but when compare with the profiler couldn't find the match.
i.e. the profiler memory's java shows 22MB
but the code getRuntimeMemoryUsage() return 12MB.
How to get the memory usage as what is shown in the profiler?
fun getRuntimeMemoryUsage(): Long {
//calculate memory usage of currently running application:
var freeSize = 0L
var totalSize = 0L
var usedSize = 0L
try {
val runtime = Runtime.getRuntime()
runtime.gc()
freeSize = runtime.freeMemory() / 1048576L
totalSize = runtime.totalMemory() / 1048576L
usedSize = (totalSize - freeSize)
val maxHeapSizeInMB = runtime.maxMemory() / 1048576L
} catch (e: Exception) {
e.printStackTrace()
}
return usedSize
}

The android studio profilers use a few different methods to capture the memory of an application. The most common method is to poll "dumpsys meminfo". However this is not something that is feasible for an app that wants to be released in the playstore.

Related

How can I generate AHB memory port in Rocket chip

I am trying to implement a Rocket chip SoC design; the SoC design will generate an AXI memory port by default. But I want to use the AHB memory port, and the Rocket chip doesn't have any configs for that. Has someone already done that?
thanks
Similar to the AXI4MemPort in subsystem/Ports.scala the general idea is to instantiate an AHBSinkNode and connecting to it through a TLToAHB widget.
trait CanHaveAhbMemPort { this: BaseSubsystem =>
private val memPortParamsOpt = p(AhbExtMem) // could also add a parameter to switch between axi/ahb
private val portName = "ahb"
private val device = new MemoryDevice
private val idBits = memPortParamsOpt.map(_.master.idBits).getOrElse(1)
val memAhbNode = AHBSlaveSinkNode( memPortParamsOpt.map({ case MemoryPortParams(memPortParams, nMemoryChannels) =>
Seq.tabulate(nMemoryChannels) { channel =>
val base = AddressSet.misaligned(memPortParams.base, memPortParams.size)
val filter = AddressSet(channel * mbus.blockBytes, ~((nMemoryChannels-1) * mbus.blockBytes))
AHBSlavePortParameters(
Seq(AHBSlaveParameters(
address = base.flatMap(_.intersect(filter)),
resources = device.reg,
regionType = RegionType.UNCACHED
executable = executable,
supportsRead = TransferSizes(1, memPortParams.beatBytes * AHBParameters.maxTransfer),
supportsWrite = TransferSizes(1, memPortParams.beatBytes * AHBParameters.maxTransfer))),
beatBytes = memPortParams.beatBytes,
lite = false)
}
}).toList.flatten)
mbus.coupleTo(s"memory_controller_port_named_$portName") {
(memAhbNode
:*= TLToAHB()
:*= TLWidthWidget(mbus.beatBytes)
:*= _)
}
Note:
I haven't tested this. This hopefully illustrated the general idea for how to swap out the mem port with AHB. There may need to be some experimentation as far as parameters and widget use goes. Hopefully, a future answer or an edit this answer can reflect the results of any testing or experience with this conversion.

PCM5122 DAC with Android Things

I have a Raspberry Pi 3B and Suptronics X920 Expansion Board which uses PCM5122 DAC. So I'm having trouble playing sounds through that board.
The config file is default except for the display configuration part:
kernel=u-boot-dtok.bin
framebuffer_depth=16
# Prevent the firmware from loading HAT overlays now that we handle pin muxing.
# ourselves. See:
# https://www.raspberrypi.org/documentation/configuration/device-tree.md#part3.4
dtoverlay=
dtparam=i2c_arm=on
dtparam=spi=on
dtparam=audio=on
# pwm and I2S are mutually-exclusive since they share hardware clocks.
dtoverlay=pwm-2chan-with-clk,pin=18,func=2,pin2=13,func2=4
dtoverlay=generic-i2s
start_x=1
# Tell U-boot to always use the "serial0" interface for the console, which is
# set to whichever uart (uart0 or uart1) is set to the header pins. This doesn't
# interfere with the uart selected for Bluetooth.
dtoverlay=chosen-serial0
# Enable skip-init on the UART interfaces, so U-Boot doesn't attempt to
# re-initialize them.
dtoverlay=rpi-uart-skip-init
# Add pin devices to the system for use by the runtime pin configuration driver.
dtoverlay=runtimepinconfig
dtoverlay=uart1
dtoverlay=bcm2710-rpi-3-b-spi0-pin-reorder
# Tell the I2S driver to use the cprman clock.
dtoverlay=bcm2710-rpi-3-b-i2s-use-cprman
# Uncomment to disable serial port on headers, use GPIO14 and GPIO15
# as gpios and to allow the core_freq to change at runtime.
enable_uart=1
core_freq=400
# Support official RPi display.
dtoverlay=i2c-rtc,ds3231
dtoverlay=rpi-ft5406
hdmi_force_hotplug=1
# Set framebuffer to support RGBA colors.
framebuffer_swap=0
# Waveshare display settings
max_usb_current=1
hdmi_group=2
hdmi_mode=87
hdmi_cvt 1024 600 60 6 0 0 0
hdmi_drive=1
This is the code for playing a sound file:
fun playSound(file: File) {
val audioEncoding = AudioFormat.ENCODING_PCM_16BIT
val sampleRate = 16000
val audioOutputFormat = AudioFormat.Builder()
.setChannelMask(AudioFormat.CHANNEL_OUT_MONO)
.setEncoding(audioEncoding)
.setSampleRate(16000)
.build()
val audioOutputBufferSize = AudioTrack.getMinBufferSize(sampleRate, audioOutputFormat.channelMask, audioEncoding)
val audioOutputDevice = findAudioDevice(AudioManager.GET_DEVICES_OUTPUTS, AudioDeviceInfo.TYPE_BUS)
val audioTrack = AudioTrack.Builder()
.setAudioFormat(audioOutputFormat)
.setBufferSizeInBytes(audioOutputBufferSize)
.setTransferMode(AudioTrack.MODE_STREAM)
.build()
audioTrack.preferredDevice = audioOutputDevice
val buffer = ByteArray(audioOutputBufferSize)
audioTrack.play()
audioTrack.setVolume(1f)
val stream = file.inputStream().buffered()
try {
while (stream.read(buffer) > 0) {
val out = audioTrack.write(buffer, 0, buffer.size, AudioTrack.WRITE_BLOCKING)
d { "audioTrack.write = $out" }
}
} catch (error: Throwable) {
e(error) { "Error playing audio $file" }
} finally {
stream.close()
}
audioTrack.stop()
audioTrack.release()
}
private fun findAudioDevice(deviceFlag: Int, deviceType: Int): AudioDeviceInfo? {
val manager = getSystemService(Context.AUDIO_SERVICE) as AudioManager
val adis = manager.getDevices(deviceFlag)
for (adi in adis) {
if (adi.type == deviceType) {
return adi
}
}
return null
}
I've tested the code with a regular Raspberry Pi audio output (which is AudioDeviceInfo.TYPE_BUILTIN_SPEAKER) and it works ok. But with AudioDeviceInfo.TYPE_BUS it just produces no sound without any errors.
I tried various config options like dtoverlay=hifiberry or dtoverlay=hifiberry-dacplus with no luck.
Please help.
It looks like you might be using some of the code for the Google Assistant sample, and you are correct to assume that TYPE_BUS is what you need to enable the audio routes to use the I2S bus instead of the built-in audio jack.
However, that is likely not the whole story. The DAC likely requires additional configuration commands and/or external triggers. Looking at a similar HAT with the same DAC, for example, there is an I2C bus connection as well for DAC setup commands. Our Assistant sample uses the VoiceHAT driver to accomplish the additional triggering required by the DAC on that peripheral.
In Raspbian, the driver you enable via dtoverlay likely takes care of both pieces. Here, your code will need to manage the setup bits manually. Look at how the VoiceHAT driver is used in the Assistant sample as an example of this.
Also, make sure you are not enabling any of the I2S pins as either GPIO or PWM, as this will disable the audio route per the documentation.
Side Note: Android Things does not support making kernel changes via config.txt, so adding drivers there is expected not to have any effect.
It's been awhile since I figured this out, so I'm posting the code that working for me so that others spend less time buried in manuals.
After I've spent a few hours reading through the manual and frowning on the board's schematic, I figured out that the PCM5122 chip needs some preconfiguration.
It turns out that this chip has a complex clocking scheme. From the datasheet:
The serial audio interface typically has 4 connections: SCK (system master clock), BCK (bit clock), LRCK (left
right word clock), and DIN (data). The device has an internal PLL that is used to take either SCK or BCK and
create the higher rate clocks required by the interpolating processor and the DAC clock. This allows the device to
operate with or without an external SCK.
So, long story short, the chip's PLL operation depends on what pin is physically wired to the Raspberry board - SCK, BCK or both:
In my case it was BCK. We need to select PLL clock source with 13th register:
With all that explained, I'll post the full driver I've used with some additional configuration. All the information you can find in the linked manual. Hope it helps.
class SuptronicsX920AudioDevice private constructor(
private val busDevice: AudioDeviceInfo,
private val i2cDevice: I2cDevice) : AudioDevice {
private var audioTrack: AudioTrack? = null
private var leftVolume = 1f
private var rightVolume = 1f
companion object {
private const val ERROR_DETECT_REG = 37
private const val ERROR_DETECT_IDCM_BIT = 3
private const val PLL_SOURCE_REG = 13
private const val PLL_SOURCE_BCK_BIT = 4
private const val AUTO_MUTE_REG = 65
private const val DIGITAL_VOLUME_LEFT_REG = 61
private const val DIGITAL_VOLUME_RIGHT_REG = 62
fun create(busDevice: AudioDeviceInfo, i2cDevice: I2cDevice): Either<IOException, SuptronicsX920AudioDevice> {
return try {
// Ignore BCK\SCK missing errors as they turn device into Power down mode
riseRegBit(i2cDevice, ERROR_DETECT_REG, ERROR_DETECT_IDCM_BIT)
// Select BCK as the source for PLL
riseRegBit(i2cDevice, PLL_SOURCE_REG, PLL_SOURCE_BCK_BIT)
// Disable auto mute for both channels
i2cDevice.writeRegByte(AUTO_MUTE_REG, 0)
// Set the maximum gain for both channels
i2cDevice.writeRegByte(DIGITAL_VOLUME_LEFT_REG, 0)
i2cDevice.writeRegByte(DIGITAL_VOLUME_RIGHT_REG, 0)
SuptronicsX920AudioDevice(busDevice, i2cDevice).right()
} catch (ioe: IOException) {
e(ioe) { "Unable to configure PCM512x for Suptronics x920" }
ioe.left()
}
}
private fun riseRegBit(i2cDevice: I2cDevice, regAddress: Int, bitAddress: Int) {
val value = i2cDevice.readRegByte(regAddress)
i2cDevice.writeRegByte(regAddress, value or (1 shl bitAddress).toByte())
}
}
override fun play(stream: InputStream, audioFormat: AudioFormat) {
val audioOutputBufferSize = AudioTrack.getMinBufferSize(
audioFormat.sampleRate,
audioFormat.channelMask,
audioFormat.encoding)
val buffer = ByteArray(audioOutputBufferSize)
audioTrack = AudioTrack.Builder()
.setAudioFormat(audioFormat)
.setBufferSizeInBytes(audioOutputBufferSize)
.setTransferMode(AudioTrack.MODE_STREAM)
.build()
audioTrack?.apply {
preferredDevice = busDevice
setStereoVolume(leftVolume, rightVolume)
play()
var bytes = 0
try {
while (stream.read(buffer) > 0) {
bytes += write(buffer, 0, buffer.size, AudioTrack.WRITE_BLOCKING)
}
} catch (error: Throwable) {
e(error) { "Error playing audio" }
}
d { "$bytes of audio track written" }
}
stop()
audioTrack = null
}
override fun stop() {
audioTrack?.apply {
if (state != AudioTrack.STATE_UNINITIALIZED) {
try {
pause()
flush()
release()
d { "Audio stopped" }
} catch (error: Throwable) {
e(error) { "Can't stop track properly" }
}
}
}
}
override fun setVolume(leftVolume: Float, rightVolume: Float) {
this.leftVolume = leftVolume
this.rightVolume = rightVolume
audioTrack?.apply { setStereoVolume(leftVolume, rightVolume) }
}
override fun close() {
stop()
i2cDevice.close()
}
}

close connection elasticsearch, is it necessary?

im create a API using scala and library Spray.IO. my API, search into elasticsearch.
my questions is also related with question.
var klt:TransportClient = EsClient_08012017.klien1
var arg = Array(JsObject(Map("id"->JsString("-1"), "item" -> JsString("-1"), "score"-> JsString("-1"))))
if(cariIndex(namaIndexCari)==true && cariIndex(namaIndexCari+"_2")==true)
{
if(hitungJumlahIndex(namaIndexCari) > hitungJumlahIndex(namaIndexCari+"_2"))
{
val ar = ambilRekomendasi(idPenggunaCari, namaTipeCari, namaIndexCari, jumlah, false)
val atd = acakTanpaDuplikat(ar)
arg = parsingJsObject(atd)
}
else
{
val ar = ambilRekomendasi(idPenggunaCari, namaTipeCari, namaIndexCari+"_2", jumlah, false)
val atd = acakTanpaDuplikat(ar)
arg = parsingJsObject(atd)
}
}
else
{
val ar = ambilRekomendasi(idPenggunaCari, namaTipeCari, namaIndexCari, jumlah, false)
val atd = acakTanpaDuplikat(ar)
arg = parsingJsObject(atd)
}
klt.close()
arg
for 1st time, hit API its fine. but, the 2nd hit API im get some error
None of the configured nodes are available: [{#transport#-1}{127.0.0.1}{127.0.0.1:9300}]
what i want to achieve are, each of hit API its also like close connection to ES and open connection. but, the reference link said "it's okay without close connections". thanks for help, or link, or reference!
Never close it unless you are closing your application

MongoDB 3.2 C# driver version 2.2.3.3 Gridfs Download large files more than 2gb

I am uploading files using the following code:
using (var s = File.OpenRead(#"C:\2gbDataTest.zip"))
{
var t = Task.Run<ObjectId>(() =>
{
return fs.UploadFromStreamAsync("2gbDataTest.zip", s);
});
return t.Result;
}
//works for the files below 2gb
var t1 = fs.DownloadAsBytesAsync(id);
Task.WaitAll(t1);
var bytes = t1.Result;
I am getting error
I am new to MongoDb and C#, can any one please show me how to download files greater than 2GB in size?
You are hitting the limit in terms of the size a byte array (kept in memory) download can be, so your only choice is to use a Stream instead like you are doing when you upload, something like (with a valid destination):
IGridFSBucket fs;
ObjectId id;
FileStream destination;
await fs.DownloadToStreamAsync(id, destination);
//Just writing complete code for others, This will work ;
//Thanks to "Adam Comerford"
var fs = new GridFSBucket(database);
using (var newFs = new FileStream(filePathToDownload, FileMode.Create))
{
//id is file objectId
var t1 = fs.DownloadToStreamAsync(id, newFs);
Task.WaitAll(t1);
newFs.Flush();
newFs.Close();
}

IronRuby performance issue while using Variables

Here is code of very simple expression evaluator using IronRuby
public class BasicRubyExpressionEvaluator
{
ScriptEngine engine;
ScriptScope scope;
public Exception LastException
{
get; set;
}
private static readonly Dictionary<string, ScriptSource> parserCache = new Dictionary<string, ScriptSource>();
public BasicRubyExpressionEvaluator()
{
engine = Ruby.CreateEngine();
scope = engine.CreateScope();
}
public object Evaluate(string expression, DataRow context)
{
ScriptSource source;
parserCache.TryGetValue(expression, out source);
if (source == null)
{
source = engine.CreateScriptSourceFromString(expression, SourceCodeKind.SingleStatement);
parserCache.Add(expression, source);
}
var result = source.Execute(scope);
return result;
}
public void SetVariable(string variableName, object value)
{
scope.SetVariable(variableName, value);
}
}
and here is problem.
var evaluator = new BasicRubyExpressionEvaluator();
evaluator.SetVariable("a", 10);
evaluator.SetVariable("b", 1 );
evaluator.Evaluate("a+b+2", null);
vs
var evaluator = new BasicRubyExpressionEvaluator();
evaluator.Evaluate("10+1+2", null);
First Is 25 times slower than second. Any suggestions? String.Replace is not a solution for me.
I do not think the performance you are seeing is due to variable setting; the first execution of IronRuby in a program is always going to be slower than the second, regardless of what you're doing, since most of the compiler isn't loaded in until code is actually run (for startup performance reasons). Please try that example again, maybe running each version of your code in a loop, and you'll see the performance is roughly equivalent; the variable-version does have some overhead of method-dispatch to get the variables, but that should be negligible if you run it enough.
Also, in your hosting code, how come you are holding onto ScriptScopes in a dictionary? I would hold onto CompiledCode (result of engine.CreateScriptSourceFromString(...).Compile()) instead -- as that will help a lot more in repeat runs.
you can of course first build the string something like
evaluator.Evaluate(string.format("a={0}; b={1}; a + b + 2", 10, 1))
Or you can make it a method
if instead of your script you return a method then you should be able to use it like a regular C# Func object.
var script = #"
def self.addition(a, b)
a + b + 2
end
"
engine.ExecuteScript(script);
var = func = scope.GetVariable<Func<object,object,object>>("addition");
func(10,1)
This is probably not a working snippet but it shows the general idea.